结合SQL查询的结果并采用所有组合

时间:2012-11-20 17:43:20

标签: sql sql-server

我在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

2 个答案:

答案 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)

我估计在您的示例数据中,S1S5有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在目的地站点的查询中添加了最终条件。我不确定这是否是一项要求,但无论如何它都不会影响S1S5的结果。这很容易收回。


基于此数据设置:

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')