如何在 sql 服务器的 table 上迭代多行中的相同 ID?
how to iterate on a table in sql server for the same id in many rows?
我有一个名为 city
的 table 和一个名为 routes_
的 table。
它们之间的关系是多对多的,所以我在它们之间使用了一个名为 map
的 table。
routes_
table 有路线名称
city
table 有城市的坐标。
map
table 包含每条路线的所有城市及其在路线中的顺序:
CREATE TABLE city
(
ID int IDENTITY(1,1) PRIMARY KEY not null ,
name varchar(50) UNIQUE,
populationOfCity int not null,
center char (10) not null,
gover_id int null,
cordinates geography null,
);
CREATE TABLE routes_
(
ID int IDENTITY(1,1) PRIMARY KEY not null,
name varchar (50) not null,
);
CREATE TABLE map
(
ID int IDENTITY(1,1) PRIMARY KEY not null ,
orderOfcity int not null,
city_id int not null,
route_id int not null,
FOREIGN KEY( city_id )REFERENCES city (id),
FOREIGN KEY( route_id )REFERENCES routes_ (id)
);
我需要找到最长的路线。
我写这个算法是为了找到它,但实际上我对 sql 服务器的语法完全陌生,所以我需要一些帮助来编写它
- 我使用地理类型通过
stdDistance
查找两个城市之间的距离。
- 我想
group by
地图 table route_id 所以我将每条路线的城市分组
- 按
orederOfcity
对地图table排序,计算距离
- 在地图 table 分组和排序后进行迭代,并在相同的情况下循环查找每条路线的距离 route_id
- 将每个根的距离保存在一个数组中,然后找到最大值。
我开始写这个但是我不知道如何用循环语法完成
SELECT map.route_id FROM map group by map.route_id order by MIN(map.orderOfcity)
declare @i int
declare @numOfRows int
set @i=1
set @numOfRows=(SELECT COUNT (*) from map )
while @i<@numOfRows
这是表格的插入语句:
插入城市:
INSERT INTO city (name,populationOfCity,cordinates,center)
VALUES ('Damascus',3140000,geography::STGeomFromText('POINT(0.0275361 51.5064694)', 4326),'yes');
INSERT INTO city (name,populationOfCity,cordinates,center)
VALUES ('Alepo',3140000,geography::STGeomFromText('POINT(-66.1711278 -17.4125)', 4326),'Yes');
INSERT INTO city (name,populationOfCity,cordinates,center)
VALUES ('Hama',725000, geography::STGeomFromText('POINT(036.6666667 35.0833333)', 4326),'yes');
INSERT INTO city (name,populationOfCity,cordinates,center)
VALUES ('Homs',1033000, geography::STGeomFromText('POINT(036.7500000 34.6666667)', 4326),'yes');
INSERT INTO city (name,populationOfCity,cordinates,center)
VALUES ('Latakia',554000, geography::STGeomFromText('POINT(035.7500000 35.5000000)', 4326),'yes');
INSERT INTO city (name,populationOfCity,cordinates,center)
VALUES ('Tartus',393054, geography::STGeomFromText('POINT(035.9166667 34.9166667)', 4326),'yes');
INSERT INTO city (name,populationOfCity,cordinates,center,gover_id)
VALUES ('Al_Bab',20000, geography::STGeomFromText('POINT(037.4833333 36.3833333)', 4326),'No',2);
INSERT INTO city (name,populationOfCity,cordinates,center)
VALUES ('Afrin',24000, geography::STGeomFromText('POINT(036.8333333 36.5333333)', 4326),'No');
INSERT INTO city (name,populationOfCity,cordinates,center)
VALUES ('As Safirah',14000, geography::STGeomFromText('POINT(037.3500000 36.0833333)', 4326),'No');
INSERT INTO city (name,populationOfCity,cordinates,center)
VALUES ('Manbij',26000, geography::STGeomFromText('POINT(037.9500000 36.5166667)', 4326),'No');
INSERT INTO city (name,populationOfCity,cordinates,center)
VALUES ('Azaz',34000, geography::STGeomFromText('POINT(037.0666667 36.6000000)', 4326),'No');
插入路线:
INSERT INTO routes_(name) VALUES ('Al_Bab___Afrin');
INSERT INTO routes_(name) VALUES ('As Safirah___Azaz');
INSERT INTO routes_(name) VALUES ('Damascus___Latakia');
INSERT INTO routes_(name) VALUES ('Tartous___Damascus');
插入地图:
INSERT INTO map(orderOfcity,city_id,route_id) VALUES (1,7,1);
INSERT INTO map(orderOfcity,city_id,route_id) VALUES (2,9,1);
INSERT INTO map(orderOfcity,city_id,route_id) VALUES (3,8,1);
----As Safirah___Azaz
INSERT INTO map(orderOfcity,city_id,route_id) VALUES (1,9,2);
INSERT INTO map(orderOfcity,city_id,route_id) VALUES (2,8,2);
INSERT INTO map(orderOfcity,city_id,route_id) VALUES (3,10,2);
INSERT INTO map(orderOfcity,city_id,route_id) VALUES (4,11,2);
INSERT INTO map(orderOfcity,city_id,route_id) VALUES (1,6,4);
INSERT INTO map(orderOfcity,city_id,route_id) VALUES (2,4,4);
INSERT INTO map(orderOfcity,city_id,route_id) VALUES (3,6,4);
迭代必须在地图的table上,我将它按routes_id分组并按orderOfCity排序,所以我知道每条路线的城市,然后我应该计算距离对于每个组,为此我应该在地图上迭代 table 并根据具有相同 route_id 计算城市之间的距离
如果在路线中有这个例子:
1)Al_Bab___Afrin
2)作为Safirah___Azaz'
在地图上,它的城市是:
al bab, As Safirah,Afrin
地图中的这个城市有 routes_id =1
所以我应该计算它们之间的距离
然后移动到 mab 中的下一个 route_id,即 2 并对其城市进行相同的计算。
您可以在 cordinates
和下一个坐标之间使用 LEAD()
to get the next cordinates
in a given route. you can then use STDistance
来计算路线中两个城市之间的距离。
使用 CTE 或派生查询 GROUP BY Route.ID
并执行 SUM(Distance of cordinates)
.
像这样
查询
;WITH CTE AS
(
SELECT R.ID,
cordinates.STDistance(LEAD(cordinates)OVER(PARTITION BY r.id ORDER BY orderOfcity ASC)) as Distance
FROM city c
INNER JOIN map m on c.id = m.city_id
INNER JOIN routes_ r on r.id = m.route_id
)
SELECT TOP 1 ID,SUM(Distance)
FROM CTE
GROUP BY ID
ORDER BY SUM(Distance) DESC
输出
2 247811.559896733
尝试使用 JOIN 连接到 MAP 中的连续行 table:
SELECT R.Name as RouteName,
SUM(C.cordinates.STDistance(C2.cordinates)) As Distance
FROM routes_ R
INNER JOIN Map M
ON M.route_id = R.Id
INNER JOIN City C
ON M.city_id = C.ID
INNER JOIN Map M2
ON M2.route_id = R.Id AND M2.orderOfcity = M.orderOfcity + 1
INNER JOIN City C2
ON C2.Id = M2.city_id
GROUP BY R.Name
这给出:
RouteName Distance
--------- --------------------------
Al_Bab___Afrin 103547.016615796
As Safirah___Azaz 247811.559896733
Tartous___Damascus 162303.402745115
要仅检索最长的路线,请使用:
SELECT TOP 1 R.Name as RouteName,
SUM(C.cordinates.STDistance(C2.cordinates)) As Distance
FROM routes_ R
INNER JOIN Map M
ON M.route_id = R.Id
INNER JOIN City C
ON M.city_id = C.ID
INNER JOIN Map M2
ON M2.route_id = R.Id AND M2.orderOfcity = M.orderOfcity + 1
INNER JOIN City C2
ON C2.Id = M2.city_id
GROUP BY R.Name
ORDER BY SUM(C.cordinates.STDistance(C2.cordinates)) DESC
我有一个名为 city
的 table 和一个名为 routes_
的 table。
它们之间的关系是多对多的,所以我在它们之间使用了一个名为 map
的 table。
routes_
table 有路线名称
city
table 有城市的坐标。
map
table 包含每条路线的所有城市及其在路线中的顺序:
CREATE TABLE city
(
ID int IDENTITY(1,1) PRIMARY KEY not null ,
name varchar(50) UNIQUE,
populationOfCity int not null,
center char (10) not null,
gover_id int null,
cordinates geography null,
);
CREATE TABLE routes_
(
ID int IDENTITY(1,1) PRIMARY KEY not null,
name varchar (50) not null,
);
CREATE TABLE map
(
ID int IDENTITY(1,1) PRIMARY KEY not null ,
orderOfcity int not null,
city_id int not null,
route_id int not null,
FOREIGN KEY( city_id )REFERENCES city (id),
FOREIGN KEY( route_id )REFERENCES routes_ (id)
);
我需要找到最长的路线。 我写这个算法是为了找到它,但实际上我对 sql 服务器的语法完全陌生,所以我需要一些帮助来编写它
- 我使用地理类型通过
stdDistance
查找两个城市之间的距离。 - 我想
group by
地图 table route_id 所以我将每条路线的城市分组 - 按
orederOfcity
对地图table排序,计算距离 - 在地图 table 分组和排序后进行迭代,并在相同的情况下循环查找每条路线的距离 route_id
- 将每个根的距离保存在一个数组中,然后找到最大值。
我开始写这个但是我不知道如何用循环语法完成
SELECT map.route_id FROM map group by map.route_id order by MIN(map.orderOfcity)
declare @i int
declare @numOfRows int
set @i=1
set @numOfRows=(SELECT COUNT (*) from map )
while @i<@numOfRows
这是表格的插入语句: 插入城市:
INSERT INTO city (name,populationOfCity,cordinates,center)
VALUES ('Damascus',3140000,geography::STGeomFromText('POINT(0.0275361 51.5064694)', 4326),'yes');
INSERT INTO city (name,populationOfCity,cordinates,center)
VALUES ('Alepo',3140000,geography::STGeomFromText('POINT(-66.1711278 -17.4125)', 4326),'Yes');
INSERT INTO city (name,populationOfCity,cordinates,center)
VALUES ('Hama',725000, geography::STGeomFromText('POINT(036.6666667 35.0833333)', 4326),'yes');
INSERT INTO city (name,populationOfCity,cordinates,center)
VALUES ('Homs',1033000, geography::STGeomFromText('POINT(036.7500000 34.6666667)', 4326),'yes');
INSERT INTO city (name,populationOfCity,cordinates,center)
VALUES ('Latakia',554000, geography::STGeomFromText('POINT(035.7500000 35.5000000)', 4326),'yes');
INSERT INTO city (name,populationOfCity,cordinates,center)
VALUES ('Tartus',393054, geography::STGeomFromText('POINT(035.9166667 34.9166667)', 4326),'yes');
INSERT INTO city (name,populationOfCity,cordinates,center,gover_id)
VALUES ('Al_Bab',20000, geography::STGeomFromText('POINT(037.4833333 36.3833333)', 4326),'No',2);
INSERT INTO city (name,populationOfCity,cordinates,center)
VALUES ('Afrin',24000, geography::STGeomFromText('POINT(036.8333333 36.5333333)', 4326),'No');
INSERT INTO city (name,populationOfCity,cordinates,center)
VALUES ('As Safirah',14000, geography::STGeomFromText('POINT(037.3500000 36.0833333)', 4326),'No');
INSERT INTO city (name,populationOfCity,cordinates,center)
VALUES ('Manbij',26000, geography::STGeomFromText('POINT(037.9500000 36.5166667)', 4326),'No');
INSERT INTO city (name,populationOfCity,cordinates,center)
VALUES ('Azaz',34000, geography::STGeomFromText('POINT(037.0666667 36.6000000)', 4326),'No');
插入路线:
INSERT INTO routes_(name) VALUES ('Al_Bab___Afrin');
INSERT INTO routes_(name) VALUES ('As Safirah___Azaz');
INSERT INTO routes_(name) VALUES ('Damascus___Latakia');
INSERT INTO routes_(name) VALUES ('Tartous___Damascus');
插入地图:
INSERT INTO map(orderOfcity,city_id,route_id) VALUES (1,7,1);
INSERT INTO map(orderOfcity,city_id,route_id) VALUES (2,9,1);
INSERT INTO map(orderOfcity,city_id,route_id) VALUES (3,8,1);
----As Safirah___Azaz
INSERT INTO map(orderOfcity,city_id,route_id) VALUES (1,9,2);
INSERT INTO map(orderOfcity,city_id,route_id) VALUES (2,8,2);
INSERT INTO map(orderOfcity,city_id,route_id) VALUES (3,10,2);
INSERT INTO map(orderOfcity,city_id,route_id) VALUES (4,11,2);
INSERT INTO map(orderOfcity,city_id,route_id) VALUES (1,6,4);
INSERT INTO map(orderOfcity,city_id,route_id) VALUES (2,4,4);
INSERT INTO map(orderOfcity,city_id,route_id) VALUES (3,6,4);
迭代必须在地图的table上,我将它按routes_id分组并按orderOfCity排序,所以我知道每条路线的城市,然后我应该计算距离对于每个组,为此我应该在地图上迭代 table 并根据具有相同 route_id 计算城市之间的距离 如果在路线中有这个例子: 1)Al_Bab___Afrin 2)作为Safirah___Azaz' 在地图上,它的城市是: al bab, As Safirah,Afrin 地图中的这个城市有 routes_id =1 所以我应该计算它们之间的距离 然后移动到 mab 中的下一个 route_id,即 2 并对其城市进行相同的计算。
您可以在 cordinates
和下一个坐标之间使用 LEAD()
to get the next cordinates
in a given route. you can then use STDistance
来计算路线中两个城市之间的距离。
使用 CTE 或派生查询 GROUP BY Route.ID
并执行 SUM(Distance of cordinates)
.
像这样
查询
;WITH CTE AS
(
SELECT R.ID,
cordinates.STDistance(LEAD(cordinates)OVER(PARTITION BY r.id ORDER BY orderOfcity ASC)) as Distance
FROM city c
INNER JOIN map m on c.id = m.city_id
INNER JOIN routes_ r on r.id = m.route_id
)
SELECT TOP 1 ID,SUM(Distance)
FROM CTE
GROUP BY ID
ORDER BY SUM(Distance) DESC
输出
2 247811.559896733
尝试使用 JOIN 连接到 MAP 中的连续行 table:
SELECT R.Name as RouteName,
SUM(C.cordinates.STDistance(C2.cordinates)) As Distance
FROM routes_ R
INNER JOIN Map M
ON M.route_id = R.Id
INNER JOIN City C
ON M.city_id = C.ID
INNER JOIN Map M2
ON M2.route_id = R.Id AND M2.orderOfcity = M.orderOfcity + 1
INNER JOIN City C2
ON C2.Id = M2.city_id
GROUP BY R.Name
这给出:
RouteName Distance
--------- --------------------------
Al_Bab___Afrin 103547.016615796
As Safirah___Azaz 247811.559896733
Tartous___Damascus 162303.402745115
要仅检索最长的路线,请使用:
SELECT TOP 1 R.Name as RouteName,
SUM(C.cordinates.STDistance(C2.cordinates)) As Distance
FROM routes_ R
INNER JOIN Map M
ON M.route_id = R.Id
INNER JOIN City C
ON M.city_id = C.ID
INNER JOIN Map M2
ON M2.route_id = R.Id AND M2.orderOfcity = M.orderOfcity + 1
INNER JOIN City C2
ON C2.Id = M2.city_id
GROUP BY R.Name
ORDER BY SUM(C.cordinates.STDistance(C2.cordinates)) DESC