邹健写的公交车路线查询(包括转车近到远排列)。
之前做过,速度跟不上
--示例数据
create table Line(lineID int,state nvarchar(10),orderid int,primary key(lineID,orderid))
insert Line select 1,'鼓楼' ,1
union all select 1,'新街口',2
union all select 1,'汽车站',3
union all select 1,'火车站',4
union all select 2,'新街口',1
union all select 2,'飞机场',2
union all select 2,'天安门',3
union all select 3,'天安门',1
union all select 3,'石门坎',2
union all select 3,'驾校' ,3
go
--查询的存储过程
create proc p_qry
@begin_state nvarchar(10),
@end_state nvarchar(10)
as
set nocount on
declare @l int
set @l=0
select lineID,line=cast('('+rtrim(lineID)+': '+rtrim(state) as varchar(8000))
,state,orderid=orderid+1,level=@l,gid=1
into #t from Line where state=@begin_state
while @@rowcount>0 and not exists(select * from #t where state=@end_state)
begin
set @l=@l+1
insert #t(line,lineID,state,orderid,level,gid)
select
line=a.line+case
when a.lineID=b.lineID
then '->'+rtrim(b.state)
else ') => ('+rtrim(b.lineID)+': '+rtrim(b.state)
end,
lineID=b.lineID,state=b.state,orderid=b.orderid+1,@l,
case when a.lineID=b.lineID then a.gid else a.gid+1 end
from #t a,Line b
where a.level=@l-1
and(
a.lineID=b.lineID and a.orderid=b.orderid
or
a.state=b.state and a.lineID<>b.lineID)
end
select 起点站=@begin_state
,终点站=@end_state
,转车次数=gid
,经过站数=case when gid<3 then @l else @l-gid+2 end
,乘车线路=line+')'
from #t where level=@l and state=@end_state
go
--调用
exec p_qry '鼓楼','火车站'
exec p_qry '鼓楼','飞机场'
exec p_qry '鼓楼','石门坎'
go
--删除测试
drop table Line
drop proc p_qry
create table Line(lineID int,state nvarchar(10),orderid int,primary key(lineID,orderid))
insert Line select 1,'鼓楼' ,1
union all select 1,'新街口',2
union all select 1,'汽车站',3
union all select 1,'火车站',4
union all select 2,'新街口',1
union all select 2,'飞机场',2
union all select 2,'天安门',3
union all select 3,'天安门',1
union all select 3,'石门坎',2
union all select 3,'驾校' ,3
go
--查询的存储过程
create proc p_qry
@begin_state nvarchar(10),
@end_state nvarchar(10)
as
set nocount on
declare @l int
set @l=0
select lineID,line=cast('('+rtrim(lineID)+': '+rtrim(state) as varchar(8000))
,state,orderid=orderid+1,level=@l,gid=1
into #t from Line where state=@begin_state
while @@rowcount>0 and not exists(select * from #t where state=@end_state)
begin
set @l=@l+1
insert #t(line,lineID,state,orderid,level,gid)
select
line=a.line+case
when a.lineID=b.lineID
then '->'+rtrim(b.state)
else ') => ('+rtrim(b.lineID)+': '+rtrim(b.state)
end,
lineID=b.lineID,state=b.state,orderid=b.orderid+1,@l,
case when a.lineID=b.lineID then a.gid else a.gid+1 end
from #t a,Line b
where a.level=@l-1
and(
a.lineID=b.lineID and a.orderid=b.orderid
or
a.state=b.state and a.lineID<>b.lineID)
end
select 起点站=@begin_state
,终点站=@end_state
,转车次数=gid
,经过站数=case when gid<3 then @l else @l-gid+2 end
,乘车线路=line+')'
from #t where level=@l and state=@end_state
go
--调用
exec p_qry '鼓楼','火车站'
exec p_qry '鼓楼','飞机场'
exec p_qry '鼓楼','石门坎'
go
--删除测试
drop table Line
drop proc p_qry
说得比较合理的资料
-------------------------------------
线路表:
code 线路编号
name 线路名称
buscode 车次
地点表:
stationcode 站编号
station 站名
中间表:
code 线路编号
stationcode 站编号
seqnumber 某站在线路中的顺序
=======================================
线路表:
每条线路对应一路车次。按序存放各站点。每条线路有两个方向。
站点表:
每个站点,有经过该站点的所有车次。
算法:
已知起点站A,终点站B。假设最大换乘次数3,初始值为0。
1、根据起点站获得经过该站点的车次。
2、按序分析每路车次。
3、取得某个车次获得该站点的后续站点。
4、如果发现后续站点是B,就找到一条路径。记录该路径。并退出在本线路上的搜索。如果后续站点不是B,就继续分析后续站点的后续站点。直到该线路的终点站。
5、如果该线路的后续站点不存在B,则获得该线路的经过本站点的后续站点,重复过程1~4,换乘次数加1,如果换乘次数为4则退出该线路的搜索。
6、取得第二个车次,分析同上。
7、分析完所有路线,如果不存在,就提醒用户增加换乘次数,或者打的。如果存在按换乘次数从小到大排列换乘路线。