SQL实现最优坐地铁方案

时间:2007-12-02 21:02:00  来源:  作者:
   坐地铁有时候不一定要坐最少站的,有时是希望能坐换乘次数最少的,应该怎么改造才能把所有的方案都取出来,然后按换乘次数、经过站点数依次排序?

  lineID state orderidPj7第一天空网络

  1 广州东 1Pj7第一天空网络

  1 体育中心2Pj7第一天空网络

  1 体育西 3Pj7第一天空网络

  1 烈士陵园4Pj7第一天空网络

  1 公园前 6Pj7第一天空网络

  1 西门口 7Pj7第一天空网络

  2 火车站 1Pj7第一天空网络

  2 纪念堂 2Pj7第一天空网络

  2 公园前 3Pj7第一天空网络

  2 中大 4Pj7第一天空网络

  2 客村 5Pj7第一天空网络

  2 琶洲 6Pj7第一天空网络

  2 万胜围 7Pj7第一天空网络

  3 广州东 1Pj7第一天空网络

  3 体育西 2Pj7第一天空网络

  3 珠江新城3Pj7第一天空网络

  3 客村 4Pj7第一天空网络

  3 市桥 5Pj7第一天空网络

  4 万胜围 1Pj7第一天空网络

  4 金洲 2Pj7第一天空网络

  如上面数据,想查询“广州东”至“中大”,大家通过程序计算列出全部的方案。Pj7第一天空网络

 Peak WongPj7第一天空网络

  SQL code  Pj7第一天空网络

DECLARE @tb TABLE(Pj7第一天空网络
    lineID int, state nvarchar(10), orderid int)Pj7第一天空网络
INSERT @tb Pj7第一天空网络
SELECT 1, N'广州东', 1  UNION ALLPj7第一天空网络
SELECT 1, N'体育中心', 2  UNION ALLPj7第一天空网络
SELECT 1, N'体育西', 3  UNION ALLPj7第一天空网络
SELECT 1, N'烈士陵园', 4  UNION ALLPj7第一天空网络
SELECT 1, N'公园前', 6  UNION ALLPj7第一天空网络
SELECT 1, N'西门口', 7  UNION ALLPj7第一天空网络
SELECT 2, N'火车站', 1  UNION ALLPj7第一天空网络
SELECT 2, N'纪念堂', 2  UNION ALLPj7第一天空网络
SELECT 2, N'公园前', 3  UNION ALLPj7第一天空网络
SELECT 2, N'中大', 4  UNION ALLPj7第一天空网络
SELECT 2, N'客村', 5  UNION ALLPj7第一天空网络
SELECT 2, N'琶洲', 6  UNION ALLPj7第一天空网络
SELECT 2, N'万胜围', 7  UNION ALLPj7第一天空网络
SELECT 3, N'广州东', 1  UNION ALLPj7第一天空网络
SELECT 3, N'体育西', 2  UNION ALLPj7第一天空网络
SELECT 3, N'珠江新城', 3  UNION ALLPj7第一天空网络
SELECT 3, N'客村', 4  UNION ALLPj7第一天空网络
SELECT 3, N'市桥', 5  UNION ALLPj7第一天空网络
SELECT 4, N'万胜围', 1  UNION ALLPj7第一天空网络
SELECT 4, N'金洲', 2

DECLAREPj7第一天空网络
    @state_start nvarchar(10),Pj7第一天空网络
    @state_stop nvarchar(10)Pj7第一天空网络
SELECTPj7第一天空网络
    @state_start = N'广州东',Pj7第一天空网络
    @state_stop = N'中大'
Pj7第一天空网络

-- 查询Pj7第一天空网络
DECLARE @re TABLE(Pj7第一天空网络
    path nvarchar(max),Pj7第一天空网络
    state_count int,Pj7第一天空网络
    start_lineID int,Pj7第一天空网络
    start_state nvarchar(10),Pj7第一天空网络
    current_lineID int,Pj7第一天空网络
    current_state nvarchar(10),Pj7第一天空网络
    current_orderid int,Pj7第一天空网络
    flag int,Pj7第一天空网络
    lineIDs nvarchar(max),Pj7第一天空网络
    level intPj7第一天空网络
)Pj7第一天空网络
DECLAREPj7第一天空网络
    @level int,Pj7第一天空网络
    @rows intPj7第一天空网络
SETPj7第一天空网络
    @level = 0
Pj7第一天空网络

-- 开始Pj7第一天空网络
INSERT @rePj7第一天空网络
SELECTPj7第一天空网络
    path = CONVERT(nvarchar(max), Pj7第一天空网络
            RTRIM(A.lineID) + N'{' Pj7第一天空网络
                + RTRIM(A.orderid) + N'.' + A.state Pj7第一天空网络
        ),Pj7第一天空网络
    state_count = 0,Pj7第一天空网络
    start_lineID = A.lineID,Pj7第一天空网络
    start_state = A.state,Pj7第一天空网络
    current_lineID = A.lineID,Pj7第一天空网络
    current_state = A.state,Pj7第一天空网络
    current_orderid = A.orderid,Pj7第一天空网络
    flag = CASEPj7第一天空网络
            WHEN A.state = @state_stop THEN 0Pj7第一天空网络
            ELSE NULL END,Pj7第一天空网络
    lineIDs = ',' + RTRIM(A.lineID) + ',',Pj7第一天空网络
    level = -(@level + 1)Pj7第一天空网络
FROM @tb APj7第一天空网络
WHERE state = @state_startPj7第一天空网络
SET @rows = @@ROWCOUNTPj7第一天空网络
WHILE @rows > 0Pj7第一天空网络
BEGINPj7第一天空网络
    SELECT Pj7第一天空网络
        @level = @level + 1Pj7第一天空网络
    INSERT @rePj7第一天空网络
    -- 同一 LineIDPj7第一天空网络
    SELECT Pj7第一天空网络
        path = CONVERT(nvarchar(max),Pj7第一天空网络
                A.path Pj7第一天空网络
                    + N'->'Pj7第一天空网络
                    + RTRIM(B.orderid) + N'.' + B.state Pj7第一天空网络
             ),Pj7第一天空网络
        state_count = A.state_count + 1,Pj7第一天空网络
        A.start_lineID, A.start_state,Pj7第一天空网络
        current_lineID = B.lineID,Pj7第一天空网络
        current_state = B.state,Pj7第一天空网络
        current_orderid = B.orderid,Pj7第一天空网络
        flag = CASEPj7第一天空网络
                WHEN B.state = @state_stop THEN 0Pj7第一天空网络
                ELSE A.flag END,Pj7第一天空网络
        A.lineIDs,Pj7第一天空网络
        level = @levelPj7第一天空网络
    FROM @re A, @tb BPj7第一天空网络
    WHERE A.flag <> 0Pj7第一天空网络
        AND A.level = @level - 1Pj7第一天空网络
        AND A.current_lineID = B.lineIDPj7第一天空网络
        AND A.current_orderid + A.flag = B.orderidPj7第一天空网络
    Pj7第一天空网络
    UNION ALLPj7第一天空网络
    -- 不同 LineIDPj7第一天空网络
    SELECT Pj7第一天空网络
        path = CONVERT(nvarchar(max),Pj7第一天空网络
                A.path + N')->'Pj7第一天空网络
                    + RTRIM(B.lineID) + N'{' Pj7第一天空网络
                    + RTRIM(B.orderid) + N'.' + B.state Pj7第一天空网络
             ),Pj7第一天空网络
        state_count = A.state_count + 1,Pj7第一天空网络
        A.start_lineID, A.start_state,Pj7第一天空网络
        current_lineID = B.lineID,Pj7第一天空网络
        current_state = B.state,Pj7第一天空网络
        current_orderid = B.orderid,Pj7第一天空网络
        flag = CASEPj7第一天空网络
                WHEN B.state = @state_stop THEN 0Pj7第一天空网络
                ELSE NULL END,Pj7第一天空网络
        A.lineIDs + RTRIM(B.lineID) + ',',Pj7第一天空网络
        level = - @levelPj7第一天空网络
    FROM @re A, @tb BPj7第一天空网络
    WHERE A.flag <> 0Pj7第一天空网络
        AND state_count = @level - 1Pj7第一天空网络
        AND A.current_lineID <> B.lineIDPj7第一天空网络
        AND A.current_state = B.statePj7第一天空网络
        AND NOT EXISTS(Pj7第一天空网络
                SELECT * FROM @rePj7第一天空网络
                WHERE CHARINDEX(',' + RTRIM(B.lineID) + ',', A.lineIDs) > 0)Pj7第一天空网络
    SET @rows = @@ROWCOUNT
Pj7第一天空网络

    INSERT @rePj7第一天空网络
    -- 不同 LineID 的第1站正向Pj7第一天空网络
    SELECT Pj7第一天空网络
        path = CONVERT(nvarchar(max), Pj7第一天空网络
                A.path Pj7第一天空网络
                    + N'->'Pj7第一天空网络
                    + RTRIM(B.orderid) + N'.' + B.state Pj7第一天空网络
            ),Pj7第一天空网络
        state_count = A.state_count + 1,Pj7第一天空网络
        A.start_lineID, A.start_state,Pj7第一天空网络
        current_lineID = B.lineID,Pj7第一天空网络
        current_state = B.state,Pj7第一天空网络
        current_orderid = B.orderid,Pj7第一天空网络
        flag = CASEPj7第一天空网络
                WHEN B.state = @state_stop THEN 0Pj7第一天空网络
                ELSE 1 END,Pj7第一天空网络
        A.lineIDs,Pj7第一天空网络
        level = @levelPj7第一天空网络
    FROM @re A, @tb BPj7第一天空网络
    WHERE A.flag IS NULLPj7第一天空网络
        AND A.level = - @levelPj7第一天空网络
        AND A.current_lineID = B.lineIDPj7第一天空网络
        AND A.current_orderid + 1 = B.orderidPj7第一天空网络
    UNION ALLPj7第一天空网络
    -- 不同 LineID 的第1站反向Pj7第一天空网络
    SELECT Pj7第一天空网络
        path = CONVERT(nvarchar(max), Pj7第一天空网络
                A.path Pj7第一天空网络
                    + N'->'Pj7第一天空网络
                    + RTRIM(B.orderid) + N'.' + B.state Pj7第一天空网络
            ),Pj7第一天空网络
        state_count = A.state_count + 1,Pj7第一天空网络
        A.start_lineID, A.start_state,Pj7第一天空网络
        current_lineID = B.lineID,Pj7第一天空网络
        current_state = B.state,Pj7第一天空网络
        current_orderid = B.orderid,Pj7第一天空网络
        flag = CASEPj7第一天空网络
                WHEN B.state = @state_stop THEN 0Pj7第一天空网络
                ELSE - 1 END,Pj7第一天空网络
        A.lineIDs,Pj7第一天空网络
        level = @levelPj7第一天空网络
    FROM @re A, @tb BPj7第一天空网络
    WHERE A.flag IS NULLPj7第一天空网络
        AND A.level = - @levelPj7第一天空网络
        AND A.current_lineID = B.lineIDPj7第一天空网络
        AND A.current_orderid - 1 = B.orderid
Pj7第一天空网络

    SET @rows = @rows + @@ROWCOUNTPj7第一天空网络
END
Pj7第一天空网络

SELECT Pj7第一天空网络
--    *,Pj7第一天空网络
    path = path + N'}',Pj7第一天空网络
    state_countPj7第一天空网络
FROM @rePj7第一天空网络
WHERE flag = 0
Pj7第一天空网络

  结果(数字5,7是要经过多少站:Pj7第一天空网络

  3{1.广州东-> 2.体育西-> 3.珠江新城-> 4.客村)-> 2{5.客村-> 4.中大} 5Pj7第一天空网络

  1{1.广州东-> 2.体育中心-> 3.体育西)-> 3{2.体育西-> 3.珠江新城-> 4.客村)-> 2{5.客村-> 4.中大} 7Pj7第一天空网络

文章评论

共有 位天空网友发表了评论 查看完整内容

特别推荐
  • 文字广告
  • 文字广告
  • 文字广告
  • 文字广告
站长黑板报

24小时热门信息