换公交车算法
现有公交线路表tblBus,结构如下
busID stationID staTionName stationSort
B0280017 S0280030 荷花池 1
B0280017 S0280028 火车北站 2
B0280017 S0280289 二环北二段 3
B0280018 S0280011 人名北路 1
B0280018 S0280028 火车北站 2
B0280018 S0280213 五块石 3
B0280019 S0280013 五块石 1
B0280019 S0280014 二环路东二段 2
B0280019 S0280215 二环东三段 3
比如:我从“荷花池”到“二环东三段”,需要乘坐“B0280017”到“火车北站”换乘“B0280018”,到“五块石”再换乘“B0280019”到“二环东三段”
CREATE TABLE T_Line(busID nvarchar(20),stationID nvarchar(20),staTionName nvarchar(50),stationSort int)
INSERT T_Line
SELECT N 'B0280017 ',N 'S0280030 ',N '荷花池 ',1 UNION ALL
SELECT N 'B0280017 ',N 'S0280028 ',N '火车北站 ',2 UNION ALL
SELECT N 'B0280017 ',N 'S0280289 ',N '二环北二段 ',3 UNION ALL
SELECT N 'B0280018 ',N 'S0280011 ',N '人名北路 ',1 UNION ALL
SELECT N 'B0280018 ',N 'S0280028 ',N '火车北站 ',2 UNION ALL
SELECT N 'B0280018 ',N 'S0280213 ',N '五块石 ',3 UNION ALL
SELECT N 'B0280019 ',N 'S0280013 ',N '五块石 ',1 UNION ALL
SELECT N 'B0280019 ',N 'S0280014 ',N '二环路东二段 ',2 UNION ALL
SELECT N 'B0280019 ',N 'S0280215 ',N '二环东三段 ',3
GO
--乘车线路查询存储过程
CREATE PROC p_qry
@Station_Start nvarchar(10),
@Station_Stop nvarchar(10)
AS
SET NOCOUNT ON
DECLARE @l int
SET @l=0
SELECT busID,staTionName,
Line=CAST( '( '+RTRIM(busID)+ ': '+RTRIM(staTionName) as nvarchar(4000)),
stationSort=stationSort,
[Level]=@l
INTO # FROM T_Line
WHERE staTionName=@Station_Start
WHILE @@ROWCOUNT> 0
AND NOT EXISTS(SELECT * FROM # WHERE staTionName=@Station_Stop)
BEGIN
SET @l=@l+1
INSERT #(Line,busID,staTionName,stationSort,[Level])
SELECT
Line=a.Line+CASE
WHEN a.busID=b.busID THEN N '-> '+RTRIM(b.staTionName)
ELSE N ') ∝ ( '+RTRIM(b.busID)
+N ': '+RTRIM(b.staTionName) END,
b.busID,b.staTionName,b.stationSort,@l
FROM # a,T_Line b
WHERE a.[Level]=@l-1
AND(a.staTionName=b.staTionName AND a.busID <> b.busID
OR a.busID=b.busID AND(
a.stationSort=b.stationSort+1
OR
a.stationSort=b.stationSort-1))
AND LEN(a.Line) <4000
AND PATINDEX( '%[ > ] '+b.staTionName+ '[-)]% ',a.Line)=0
END
SELECT N '起点站 '=@Station_Start
,N '终点站 '=@Station_Stop
,N '乘车线路 '=Line+N ') '
FROM #
WHERE [Level]=@l
AND staTionName=@Station_Stop
IF @@ROWCOUNT =0 --如果未有可以到达的线路,则显示处理结果表备查
SELECT * FROM #
GO
--调用
EXEC p_qry N '荷花池 ',N '二环东三段 '
drop proc p_qry
drop table T_Line
/* 结果
起点站 终点站 乘车线路
---------- ---------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
荷花池 二环东三段 (B0280017: 荷花池-> 火车北站) ∝ (B0280018: 火车北站-> 五块石) ∝ (B0280019: 五块石-> 二环路东二段-> 二环东三段)
busID stationID staTionName stationSort
B0280017 S0280030 荷花池 1
B0280017 S0280028 火车北站 2
B0280017 S0280289 二环北二段 3
B0280018 S0280011 人名北路 1
B0280018 S0280028 火车北站 2
B0280018 S0280213 五块石 3
B0280019 S0280013 五块石 1
B0280019 S0280014 二环路东二段 2
B0280019 S0280215 二环东三段 3
比如:我从“荷花池”到“二环东三段”,需要乘坐“B0280017”到“火车北站”换乘“B0280018”,到“五块石”再换乘“B0280019”到“二环东三段”
CREATE TABLE T_Line(busID nvarchar(20),stationID nvarchar(20),staTionName nvarchar(50),stationSort int)
INSERT T_Line
SELECT N 'B0280017 ',N 'S0280030 ',N '荷花池 ',1 UNION ALL
SELECT N 'B0280017 ',N 'S0280028 ',N '火车北站 ',2 UNION ALL
SELECT N 'B0280017 ',N 'S0280289 ',N '二环北二段 ',3 UNION ALL
SELECT N 'B0280018 ',N 'S0280011 ',N '人名北路 ',1 UNION ALL
SELECT N 'B0280018 ',N 'S0280028 ',N '火车北站 ',2 UNION ALL
SELECT N 'B0280018 ',N 'S0280213 ',N '五块石 ',3 UNION ALL
SELECT N 'B0280019 ',N 'S0280013 ',N '五块石 ',1 UNION ALL
SELECT N 'B0280019 ',N 'S0280014 ',N '二环路东二段 ',2 UNION ALL
SELECT N 'B0280019 ',N 'S0280215 ',N '二环东三段 ',3
GO
--乘车线路查询存储过程
CREATE PROC p_qry
@Station_Start nvarchar(10),
@Station_Stop nvarchar(10)
AS
SET NOCOUNT ON
DECLARE @l int
SET @l=0
SELECT busID,staTionName,
Line=CAST( '( '+RTRIM(busID)+ ': '+RTRIM(staTionName) as nvarchar(4000)),
stationSort=stationSort,
[Level]=@l
INTO # FROM T_Line
WHERE staTionName=@Station_Start
WHILE @@ROWCOUNT> 0
AND NOT EXISTS(SELECT * FROM # WHERE staTionName=@Station_Stop)
BEGIN
SET @l=@l+1
INSERT #(Line,busID,staTionName,stationSort,[Level])
SELECT
Line=a.Line+CASE
WHEN a.busID=b.busID THEN N '-> '+RTRIM(b.staTionName)
ELSE N ') ∝ ( '+RTRIM(b.busID)
+N ': '+RTRIM(b.staTionName) END,
b.busID,b.staTionName,b.stationSort,@l
FROM # a,T_Line b
WHERE a.[Level]=@l-1
AND(a.staTionName=b.staTionName AND a.busID <> b.busID
OR a.busID=b.busID AND(
a.stationSort=b.stationSort+1
OR
a.stationSort=b.stationSort-1))
AND LEN(a.Line) <4000
AND PATINDEX( '%[ > ] '+b.staTionName+ '[-)]% ',a.Line)=0
END
SELECT N '起点站 '=@Station_Start
,N '终点站 '=@Station_Stop
,N '乘车线路 '=Line+N ') '
FROM #
WHERE [Level]=@l
AND staTionName=@Station_Stop
IF @@ROWCOUNT =0 --如果未有可以到达的线路,则显示处理结果表备查
SELECT * FROM #
GO
--调用
EXEC p_qry N '荷花池 ',N '二环东三段 '
drop proc p_qry
drop table T_Line
/* 结果
起点站 终点站 乘车线路
---------- ---------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
荷花池 二环东三段 (B0280017: 荷花池-> 火车北站) ∝ (B0280018: 火车北站-> 五块石) ∝ (B0280019: 五块石-> 二环路东二段-> 二环东三段)