乘车线路查询

原创 2008年01月02日 07:41:00
 
背景
有如下表示乘车线路和站点的数据,要求查询出指定站点之间的所有乘车线路:
USE tempdb
GO
 
-- 模拟数据
SET NOCOUNT ON
IF OBJECT_ID(N'tempdb..#tb') IS NOT NULL
    DROP TABLE #tb
CREATE TABLE #tb(
    id int IDENTITY
        PRIMARY KEY,
    lineID int,
    state nvarchar(10),
    orderid int
)
INSERT #tb(
     lineID, state, orderid)
SELECT 1, N'广州东',UNION ALL
SELECT 1, N'体育中心',UNION ALL
SELECT 1, N'体育西',UNION ALL
SELECT 1, N'烈士陵园',UNION ALL
SELECT 1, N'公园前',UNION ALL
SELECT 1, N'西门口',UNION ALL
SELECT 2, N'火车站',UNION ALL
SELECT 2, N'纪念堂',UNION ALL
SELECT 2, N'公园前',UNION ALL
SELECT 2, N'中大',UNION ALL
SELECT 2, N'客村',UNION ALL
SELECT 2, N'琶洲',UNION ALL
SELECT 2, N'万胜围',UNION ALL
SELECT 3, N'广州东',UNION ALL
SELECT 3, N'体育西',UNION ALL
SELECT 3, N'珠江新城',UNION ALL
SELECT 3, N'客村',UNION ALL
SELECT 3, N'市桥',UNION ALL
SELECT 4, N'万胜围',UNION ALL
SELECT 4, N'金洲', 2
 
CREATE INDEX IX_lineID
    ON #tb(
        lineID)
 
CREATE INDEX IX_state
    ON #tb(
        state)
 
CREATE INDEX IX_orderid
    ON #tb(
        orderid)
GO
 
处理方法:
之前也有发表过一些如何处理这个问题的方法,但效率不是太好。下面的这种方法加上了乘车方向的考虑:同一条线路上,只有两个乘车方向,而且一旦方向了,就不会再反向乘车(因为是从这个方向来,再坐回去是不合理的);如果某个站点可以换到另一条线路,则换乘后的另一条线路也是两个方向乘车。通过乘车方向的控制,减少了算法要搜索的路径。
-- 乘车路线查询
DECLARE
    @state_start nvarchar(10),
    @state_stop nvarchar(10)
SELECT
    @state_start = N'广州东',
    @state_stop = N'中大'
 
-- 查询
IF OBJECT_ID(N'tempdb..#re') IS NOT NULL
    DROP TABLE #re
CREATE TABLE #re(
    ID int IDENTITY
       PRIMARY KEY,
    path nvarchar(max),
    state_count int,
    line_count int,
    start_lineID int,
    start_state nvarchar(10),
    current_lineID int,
    current_state nvarchar(10),
    next_orderid int,
    flag int,
    lineIDs varchar(max),
    level int
)
 
CREATE INDEX IX_current_lineID
    ON #re(
       current_lineID )
 
CREATE INDEX IX_current_state
    ON #re(
       current_state )
 
CREATE INDEX IX_next_orderid
    ON #re(
       next_orderid )
 
CREATE INDEX IX_current_level
    ON #re(
       level )
 
DECLARE
    @level int,
    @rows int
SET
    @level = 0
 
-- 开始
INSERT #re(
    path,
    state_count, line_count,
    start_lineID, start_state,
    current_lineID, current_state,
    next_orderid, flag, lineIDs, level)   
SELECT
    path = CONVERT(nvarchar(max),
           RTRIM(A.lineID) + N'{'
              + RTRIM(A.orderid) + N'.' + A.state
       ),
    state_count = 0,
    line_count = 0,
    start_lineID = A.lineID,
    start_state = A.state,
    current_lineID = A.lineID,
    current_state = A.state,
    next_orderid = A.orderid,
    flag = CASE
           WHEN A.state = @state_stop THEN 0
           ELSE NULL END,
    lineIDs = ',' + RTRIM(A.lineID) + ',',
    level = -(@level + 1)
FROM #tb A
WHERE state = @state_start
SET @rows = @@ROWCOUNT
WHILE @rows > 0
BEGIN
    SELECT
       @level = @level + 1
    INSERT #re(
       path,
       state_count, line_count,
       start_lineID, start_state,
       current_lineID, current_state,
       next_orderid, flag, lineIDs, level)   
    -- 同一LineID
    SELECT
       path = CONVERT(nvarchar(max),
              A.path
                  + N'->'
                  + RTRIM(B.orderid) + N'.' + B.state
           ),
       state_count = A.state_count + 1,
       A.line_count,
       A.start_lineID, A.start_state,
       current_lineID = B.lineID,
       current_state = B.state,
       next_orderid = B.orderid + A.flag,
       flag = CASE
              WHEN B.state = @state_stop THEN 0
              ELSE A.flag END,
       A.lineIDs,
       level = @level
    FROM #re A, #tb B
    WHERE A.flag <> 0
       AND A.level = @level - 1
       AND A.current_lineID = B.lineID
       AND A.next_orderid = B.orderid
   
    UNION ALL
    -- 不同LineID
    SELECT
       path = CONVERT(nvarchar(max),
              A.path + N')->'
                  + RTRIM(B.lineID) + N'{'
                  + RTRIM(B.orderid) + N'.' + B.state
           ),
       state_count = A.state_count + 1,
       line_count = A.line_count + 1,
       A.start_lineID, A.start_state,
       current_lineID = B.lineID,
       current_state = B.state,
       next_orderid = B.orderid,
       flag = CASE
              WHEN B.state = @state_stop THEN 0
              ELSE NULL END,
       A.lineIDs + RTRIM(B.lineID) + ',',
       level = - @level
    FROM #re A, #tb B
    WHERE A.flag <> 0
       AND state_count = @level - 1
       AND A.current_lineID <> B.lineID
       AND A.current_state = B.state
       AND NOT EXISTS(
              SELECT * FROM #re
              WHERE CHARINDEX(',' + RTRIM(B.lineID) + ',', A.lineIDs) > 0)
    SET @rows = @@ROWCOUNT
 
    INSERT #re(
       path,
       state_count, line_count,
       start_lineID, start_state,
       current_lineID, current_state,
       next_orderid, flag, lineIDs, level)   
    -- 不同LineID 的第站正向
    SELECT
       path = CONVERT(nvarchar(max),
              A.path
                  + N'->'
                  + RTRIM(B.orderid) + N'.' + B.state
           ),
       state_count = A.state_count + 1,
       A.line_count,
       A.start_lineID, A.start_state,
       current_lineID = B.lineID,
       current_state = B.state,
       next_orderid = B.orderid + 1,
       flag = CASE
              WHEN B.state = @state_stop THEN 0
              ELSE 1 END,
       A.lineIDs,
       level = @level
    FROM #re A, #tb B
    WHERE A.flag IS NULL
       AND A.level = - @level
       AND A.current_lineID = B.lineID
       AND A.next_orderid + 1 = B.orderid
    UNION ALL
    -- 不同LineID 的第站反向
    SELECT
       path = CONVERT(nvarchar(max),
              A.path
                  + N'->'
                  + RTRIM(B.orderid) + N'.' + B.state
           ),
       state_count = A.state_count + 1,
       A.line_count,
       A.start_lineID, A.start_state,
       current_lineID = B.lineID,
       current_state = B.state,
       next_orderid = B.orderid - 1,
       flag = CASE
              WHEN B.state = @state_stop THEN 0
              ELSE - 1 END,
       A.lineIDs,
       level = @level
    FROM #re A, #tb B
    WHERE A.flag IS NULL
       AND A.level = - @level
       AND A.current_lineID = B.lineID
       AND A.next_orderid - 1 = B.orderid
 
    SET @rows = @rows + @@ROWCOUNT
END
 
SELECT
-- *,
    path = path + N'}',
    line_count,
    state_count
FROM #re
WHERE flag = 0
 
 

沙坪坝区高等教育自学考试考点地址及乘车线路(参考)- 自考

沙坪坝区高等教育自学考试考点地址及乘车线路(参考) 考点名称 地    址 经过该考点公交车 28中 文教村1号(磁器口) ...
  • jpr1990
  • jpr1990
  • 2012年04月13日 22:44
  • 3046

南京公交乘车查询系统

  • 2006年03月16日 00:00
  • 105KB
  • 下载

公交线路查询系统 C++实现 图

一、需求与规格说明    本次实验涉及实际问题,实现公交线路系统的增删改查功能,建立公交线路网,用户可以在威海市范围内实用。    本次实验要求分为: 1.实现根据给定的数据公交数据建立图的存储...

使用百度地图查询经过某一公交站的所有公交线路

百度提供的POI检索接口: http://lbsyun.baidu.com/index.php?title=iossdk/guide/retrieval每个检索功能模块都包括一个主检索对象,一个用于...

公交车线路查询系统

内容:经过站1路汽车:a,b,c,d..........2路汽车:e,f,c,g.........则从a-g需要在c站换车怎么算?$a = array('a','b','c','d');$b = ar...

用SQL进行地铁线路换乘查询

这代码是当初做课程作业时写出来的,过了几个月了现在看了看发现还挺不错的,说不定现在还写不出来了呢·~·。语法较为基础,都是简单的关键字,但是逻辑嵌套比较复杂,也用了大量的in,所以效率上可能不那么给力...

微信公众号开发(公交线路查询-JAVA

一、Dom4j的使用    在介绍公交线路开发之前,先简单介绍下Dom4j的使用,因为公交线路查询引用的是爱帮公交api,调用结果为xml格式文件,故用到了Dom4j这个包,当然还有其他的包来读取xm...

高德地图---线路规划查询/正向地理编码/地图覆盖物

本来想用高德地图的V3.0.0版本的搜索做天气搜索的,但是一直配置不好开发环境,最后就在原来工程里面使用V2.6.0的版本的地图做了这个简单的线路规划查询的例子。 基本功能:输入起点和终点  地图显...

保定公交线路查询系统

课程设计报告 题目: 保定公交线路查询系统 学 院 数学与计算机学院 学...

【数学建模集训系列】公交查询系统的matlab实现-公交站点和线路对应矩阵

%============================================================== % 功能: 求站点S和路线L矩阵,表示通过S的所有线路 % 日期: 8/...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:乘车线路查询
举报原因:
原因补充:

(最多只允许输入30个字)