我在SQL Server中有一个问题。我有下表:
ROUTES = the route ID
STATIONS = the station ID
ORDER = the order the train pass from the stations
STOPS? = if the train stops at this station then is equal to 1 otherwise 0
示例数据:
-----------------------------------------------------
ROUTES STATIONS ORDER STOPS?
-----------------------------------------------------
R1 S1 1 1
R1 S2 2 1
R1 S3 3 1
R1 S4 4 1
R1 S5 5 1
R2 S2 1 1
R2 S3 2 1
R2 S4 3 1
R3 S1 1 1
R3 S2 2 1
R3 S7 3 1
R3 S4 4 1
R3 S5 5 1
R3 S6 6 1
R4 S1 1 1
R4 S2 2 1
R4 S3 3 0
R4 S4 4 1
R5 S2 1 1
R5 S3 2 0
R5 S4 3 1
R6 S3 1 1
R6 S4 2 0
R6 S5 3 0
R6 S6 4 1
R7 S2 1 1
R7 S3 2 0
R7 S4 3 0
R7 S5 4 1
总之,我们有以下路线:
R1: S1-S2-S3-S4-S5
R2: S2-S3-S4
R3: S1-S2-S7-S4-S5-S6
R4: S1-S2-S3-S4
R5: S2-S3-S4
R6: S3-S4-S5-S6
R7: S2-S3-S4-S5
我们假设S2和S4是连接站
这意味着如果一条路线的火车停在那里(STOPS = 1),乘客可以从火车下车并从另一条路线乘坐另一列火车
所以我们有一张提到连接站的表
conn_stations
--------------
S2
S4
我的问题是如何获得所有可能的路线组合,例如从站S1出发并到达站S5。乘客可以根据上述数据更改路线,我们应该采取以下结果(路线):
R1: S1-S2-S3-S4-S5
R3: S1-S2-S7-S4-S5
temp1: S1-S2(from R1)-S7-S4-S5(from R3)
temp2: S1-S2(from R3)-S3-S4(from R1)-S5(from R3)
temp3: S1-S2-S3-S4(from R1)-S5(from R3)
e.t.c
我希望你明白我在问什么。
如果有帮助我有一张表格显示两个站点之间的距离,这表明哪些站点已连接
Station A Station B Distance
-------------------------------------
S1 S2 5
S2 S3 1
S2 S7 8
S3 S4 15
S4 S5 16
S5 S6 25
S7 S4 10
答案 0 :(得分:0)
我认为如果你不必在连接站和终点站之间包括所有临时站点会更容易,但这就是我为直接路线做的事情:
select sroute, sstation, sorder, eroute, estation, eorder
from
(select route as sroute, station as sstation, order as sorder
from path
where station = "s1" and stops = 1) pstart inner join
(select route as eroute, station as estation, order as eorder
from path
where station = "s5" and stops = 1) pend on
pstart.sroute = pend.eroute) direct
并通过一个连接站路由:
SELECT sroute, sstation, sorder,
croute, cstation, corder,
oroute, ostation, oorder,
p.route , p.station, p.ORDER
FROM
(SELECT sroute, sstation, sorder,
croute, cstation, corder,
p.route AS oroute, p.station AS ostation, p.ORDER AS oorder
FROM
(SELECT sroute, sstation, sorder,
p.route AS croute, p.station AS cstation, p.ORDER AS corder
FROM
(SELECT route AS sroute, station AS sstation, ORDER AS sorder
FROM path
WHERE station = "s1" AND stops = 1
) pstart INNER JOIN
path p ON
pstart.route = p.route INNER JOIN
conn_stations c ON
p.station = c.station
WHERE p.stops = 1
) conn INNER JOIN
path p ON
conn.cstation = p.station
WHERE p.stops = 1 AND p.route <> conn.route
) conn_off INNER JOIN
path p ON
conn_off.oroute = p.route
WHERE p.stops = 1 AND p.station = "s5"
但连接站的数量将反映在SQL中,您最好使用编程工具。
HTH
答案 1 :(得分:0)
我估计在您的示例数据中,S1
到S5
有39条路线(如果我的查询正确的话)。我不一定认为SQL是这项工作的正确工具(特别是如果根据评论,路由变为双向)。
查询:
declare @StartStation char(2)
declare @EndStation char(2)
select @StartStation = 'S1'
select @EndStation = 'S5'
;With PartialRoutes as (
select Route,Station,CONVERT(varchar(max),Station) as CurrentPath,RouteOrder,1 as HasTransferred,CONVERT(varchar(max),Route) as RoutesTaken,Stop
from
@Routes r
where
r.Station = @StartStation and r.Stop = 1
union all
--Continue on current route
select pr.Route,r.Station,pr.CurrentPath + '-' + r.Station,r.RouteOrder,0,RoutesTaken,r.Stop
from
PartialRoutes pr
inner join
@Routes r
on
pr.Route = r.Route and
pr.RouteOrder = r.RouteOrder - 1
union all
--Transfers
select r.Route,r.Station,pr.CurrentPath,r.RouteOrder,1,RoutesTaken + '-' + r.Station + '(' + pr.Route + ',' + r.Route + ')',r.Stop
from
PartialRoutes pr
inner join
@Connections c
on
pr.Station = c.Station
inner join
@Routes r
on
pr.Route != r.Route and
pr.Station = r.Station
where
pr.HasTransferred = 0 --Prevents us transferring multiple times in a single station
and r.Stop = 1
)
select * from PartialRoutes where Station = @EndStation and Stop=1 option (MAXRECURSION 0)
结果:
Route Station CurrentPath RouteOrder HasTransferred RoutesTaken
----- ------- ------------------- ----------- -------------- --------------------------
R7 S5 S1-S2-S3-S4-S5 4 0 R4-S2(R4,R7)
R3 S5 S1-S2-S3-S4-S5 5 0 R4-S2(R4,R7)-S4(R7,R3)
R1 S5 S1-S2-S3-S4-S5 5 0 R4-S2(R4,R7)-S4(R7,R1)
R3 S5 S1-S2-S3-S4-S5 5 0 R4-S2(R4,R5)-S4(R5,R3)
R1 S5 S1-S2-S3-S4-S5 5 0 R4-S2(R4,R5)-S4(R5,R1)
R3 S5 S1-S2-S7-S4-S5 5 0 R4-S2(R4,R3)
R1 S5 S1-S2-S7-S4-S5 5 0 R4-S2(R4,R3)-S4(R3,R1)
R3 S5 S1-S2-S3-S4-S5 5 0 R4-S2(R4,R2)-S4(R2,R3)
R1 S5 S1-S2-S3-S4-S5 5 0 R4-S2(R4,R2)-S4(R2,R1)
R1 S5 S1-S2-S3-S4-S5 5 0 R4-S2(R4,R1)
R3 S5 S1-S2-S3-S4-S5 5 0 R4-S2(R4,R1)-S4(R1,R3)
R3 S5 S1-S2-S3-S4-S5 5 0 R4-S4(R4,R3)
R1 S5 S1-S2-S3-S4-S5 5 0 R4-S4(R4,R1)
R7 S5 S1-S2-S3-S4-S5 4 0 R3-S2(R3,R7)
R3 S5 S1-S2-S3-S4-S5 5 0 R3-S2(R3,R7)-S4(R7,R3)
R1 S5 S1-S2-S3-S4-S5 5 0 R3-S2(R3,R7)-S4(R7,R1)
R3 S5 S1-S2-S3-S4-S5 5 0 R3-S2(R3,R5)-S4(R5,R3)
R1 S5 S1-S2-S3-S4-S5 5 0 R3-S2(R3,R5)-S4(R5,R1)
R3 S5 S1-S2-S3-S4-S5 5 0 R3-S2(R3,R4)-S4(R4,R3)
R1 S5 S1-S2-S3-S4-S5 5 0 R3-S2(R3,R4)-S4(R4,R1)
R3 S5 S1-S2-S3-S4-S5 5 0 R3-S2(R3,R2)-S4(R2,R3)
R1 S5 S1-S2-S3-S4-S5 5 0 R3-S2(R3,R2)-S4(R2,R1)
R1 S5 S1-S2-S3-S4-S5 5 0 R3-S2(R3,R1)
R3 S5 S1-S2-S3-S4-S5 5 0 R3-S2(R3,R1)-S4(R1,R3)
R3 S5 S1-S2-S7-S4-S5 5 0 R3
R1 S5 S1-S2-S7-S4-S5 5 0 R3-S4(R3,R1)
R7 S5 S1-S2-S3-S4-S5 4 0 R1-S2(R1,R7)
R3 S5 S1-S2-S3-S4-S5 5 0 R1-S2(R1,R7)-S4(R7,R3)
R1 S5 S1-S2-S3-S4-S5 5 0 R1-S2(R1,R7)-S4(R7,R1)
R3 S5 S1-S2-S3-S4-S5 5 0 R1-S2(R1,R5)-S4(R5,R3)
R1 S5 S1-S2-S3-S4-S5 5 0 R1-S2(R1,R5)-S4(R5,R1)
R3 S5 S1-S2-S3-S4-S5 5 0 R1-S2(R1,R4)-S4(R4,R3)
R1 S5 S1-S2-S3-S4-S5 5 0 R1-S2(R1,R4)-S4(R4,R1)
R3 S5 S1-S2-S7-S4-S5 5 0 R1-S2(R1,R3)
R1 S5 S1-S2-S7-S4-S5 5 0 R1-S2(R1,R3)-S4(R3,R1)
R3 S5 S1-S2-S3-S4-S5 5 0 R1-S2(R1,R2)-S4(R2,R3)
R1 S5 S1-S2-S3-S4-S5 5 0 R1-S2(R1,R2)-S4(R2,R1)
R1 S5 S1-S2-S3-S4-S5 5 0 R1
R3 S5 S1-S2-S3-S4-S5 5 0 R1-S4(R1,R3)
我在末尾添加了一列,显示了所遵循的路线,例如R4-S2(R4,R7)-S4(R7,R6)
表示他们在路线R4
上开始,然后在S2
他们转移到路线R7
,然后在S4
转移到路线R6
希望您可以根据需要接受此查询并进行修改(即我仍然不知道您问题中最终表格的相关性)。
编辑我在列车需要Stop
在目的地站点的查询中添加了最终条件。我不确定这是否是一项要求,但无论如何它都不会影响S1
到S5
的结果。这很容易收回。
基于此数据设置:
declare @Routes table (Route char(2) not null, Station char(2) not null,RouteOrder int not null,Stop bit not null)
insert into @Routes (Route,Station,RouteOrder,Stop) values
('R1','S1',1,1),('R1','S2',2,1),('R1','S3',3,1),('R1','S4',4,1),('R1','S5',5,1),
('R2','S2',1,1),('R2','S3',2,1),('R2','S4',3,1),
('R3','S1',1,1),('R3','S2',2,1),('R3','S7',3,1),('R3','S4',4,1),('R3','S5',5,1),('R3','S6',6,1),
('R4','S1',1,1),('R4','S2',2,1),('R4','S3',3,0),('R4','S4',4,1),
('R5','S2',1,1),('R5','S3',2,0),('R5','S4',3,1),
('R6','S3',1,1),('R6','S4',2,0),('R6','S5',3,0),('R6','S6',4,1),
('R7','S2',1,1),('R7','S3',2,0),('R7','S4',3,0),('R7','S5',4,1)
declare @Connections table (Station char(2) not null)
insert into @Connections (Station) values ('S2'),('S4')