如何在 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 服务器的语法完全陌生,所以我需要一些帮助来编写它

  1. 我使用地理类型通过 stdDistance 查找两个城市之间的距离。
  2. 我想 group by 地图 table route_id 所以我将每条路线的城市分组
  3. orederOfcity对地图table排序,计算距离
  4. 在地图 table 分组和排序后进行迭代,并在相同的情况下循环查找每条路线的距离 route_id
  5. 将每个根的距离保存在一个数组中,然后找到最大值。

我开始写这个但是我不知道如何用循环语法完成

 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

SQL Fiddle

尝试使用 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