?? gongjiaoxinlu2.txt
字號:
這幾天在做一個(gè)公交乘車路線查詢應(yīng)用,遇到了很多人都遇到的一個(gè)問題,就是如何快速查詢出直達(dá)路線、轉(zhuǎn)乘路線,而不需要進(jìn)行復(fù)雜的算法編程。本人在參考了CSDN上很多牛人的經(jīng)驗(yàn)后,做出一個(gè)不用Dijkstra、弗洛伊德等算法,不需要圖或鄰接表等復(fù)雜數(shù)據(jù)結(jié)構(gòu),使用純SQL存儲過程的實(shí)現(xiàn)方法。
首先說明,這個(gè)方法只能實(shí)現(xiàn)直達(dá)路線、一次轉(zhuǎn)乘的查詢,而且不考慮最短路徑等因素。如果轉(zhuǎn)乘次數(shù)超過1次,那就不得不考慮尋找其它更好的方法了。
思路:直達(dá)的情況很簡單,直接可以查詢出來;一次轉(zhuǎn)乘時(shí),把所有包含起始站點(diǎn)和到達(dá)站點(diǎn)的路線分揀到2張臨時(shí)表中,在這兩張表中查詢同時(shí)包含某個(gè)換乘站點(diǎn),并且該站點(diǎn)在起始線路中起始站點(diǎn)之后、到達(dá)線路中到達(dá)站點(diǎn)之前,這樣就能查詢出來了;>1次轉(zhuǎn)乘,查不出來:)
以下是實(shí)現(xiàn)方法:
1.用表tb_kmbusstations存放所有站點(diǎn)的集合
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[tb_kmbusstations]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[tb_kmbusstations]
GO
CREATE TABLE [dbo].[tb_kmbusstations] (
[idx] [int] IDENTITY (1, 1) NOT NULL ,
[station] [nvarchar] (200) COLLATE Chinese_PRC_CI_AS NULL
) ON [PRIMARY]
GO
insert into tb_kmbusstations(station) select '12棵橡樹莊園小區(qū)'
union all select '阿拉辦事處'
union all select '阿拉中學(xué)'
union all select '阿依村'
union all select '安吉路口'
union all select '安康路'
union all select '安康路口(西園路口)'
union all select '安全新村'
union all select '八公里(貴昆路)'
union all select '巴士家園'
union all select '白龍村'
union all select '白龍路(昆理工大新迎區(qū))'
union all select '白龍路口(白云路)'
union all select '白龍寺(白龍路)'
union all select '白馬'
union all select '白沙河'
union all select '白沙路口(春雨路)'
union all select '白水塘'
union all select '白水塘上村'
union all select '白水塘中村'
union all select '白塔路(銀河證券)'
union all select '白塔路口(人民東路)'
union all select '白塔路口(人民東路口)'
union all select '白塔路口(世博大廈)'
union all select '白藥廠'
union all select '白云路(北京路口)'
union all select '白云路(東段)'
union all select '白云路口(北京路)'
union all select '白云路西口'
union all select '百匯商場'
union all select '班莊村'
union all select '班莊村口'
union all select '寶海公園'
................. //數(shù)據(jù)較多(900多個(gè)站點(diǎn)),已省略,如有需要,請聯(lián)系我
2.用kmbusline存放所有公交線路
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[kmbusline]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[kmbusline]
GO
CREATE TABLE [dbo].[kmbusline] (
[busname] [varchar] (100) COLLATE Chinese_PRC_CI_AS NOT NULL , --線路名稱
[svctime] [char] (30) COLLATE Chinese_PRC_CI_AS NULL , --開行時(shí)間
[stoe] [varchar] (200) COLLATE Chinese_PRC_CI_AS NULL , --起始站/終到站
[line] [varchar] (4000) COLLATE Chinese_PRC_CI_AS NULL --線路
) ON [PRIMARY]
GO
insert into kmbusline(busname,line)
select '7路去程','潘家灣→昆師路口→昆師路口→潘家灣→市體育館(人民西路)→紅菱路(昆明肝病醫(yī)院)→茭菱路口(省現(xiàn)代婦產(chǎn)科醫(yī)院)→茭菱路(蕰莎堡)→西園路口(茭菱路)→豐寧小區(qū)→正大電子城→泰和園→普爾斯馬特會(huì)員店→黃土坡立交橋→西部客運(yùn)站→海源中路口(昆瑞路)→西山二中→三家巷→黑林鋪→昆瑞路→加工廠(昆瑞路)→昭宗路口(昆瑞路)→眠山(春雨路)→七公里(春雨路)→昆明制藥廠→昭宗大村(七四三四工廠)→[終到站]'
union all select '25路去程','江東花城→霖雨橋(霖雨路東)→霖雨橋(北京路口)→江東花園(江東花園北路)→江東商業(yè)街→北辰中路→北辰小區(qū)→金菊路口(金實(shí)路)→金實(shí)小區(qū)→云南茶葉市場→白云路(北京路口)→王旗營(萬宏路)→萬宏路(龍泉花園)→聯(lián)盟路(萬宏路口)→聯(lián)盟路口(穿金路口)→席子營(環(huán)城東路)→昆明理工大學(xué)(新迎區(qū))→延安醫(yī)院(環(huán)城東路)→董家灣→東站(環(huán)城東路)→民航路口(環(huán)城南路)→吳井橋→北京路(環(huán)城南路口)→昆明站(北京路)→[終到站]'
union all select '25路回程','昆明站(北京路)→北京路(環(huán)城南路口)→吳井橋→民航路口(環(huán)城南路)→東站(環(huán)城東路)→董家灣→延安醫(yī)院(環(huán)城東路)→昆明理工大學(xué)(新迎區(qū))→席子營(環(huán)城東路)→聯(lián)盟路口(穿金路口)→聯(lián)盟路(萬宏路口)→萬宏路(龍泉花園)→王旗營(萬宏路)→金星東門→金江路→金星西門→金夏路(北京路口)→金實(shí)小區(qū)→金菊路口(金實(shí)路)→北辰小區(qū)→北辰中路→江東商業(yè)街→江東花園(江東花園北路)→霖雨橋(霖雨路東)→江東花城→[終到站]'
union all select '26路去程','黃土坡(昆瑞路)→云南財(cái)貿(mào)學(xué)院(西區(qū))(昆瑞路)→麻園→西園路口(工人醫(yī)院)(昆瑞路)→西站→建設(shè)路(師大附中)→百匯商場→小西門(東風(fēng)西路)→藝術(shù)劇院→護(hù)國橋(東風(fēng)廣場)→塘子巷→和平村(北京路)→北京路(環(huán)城南路口)→吳井橋→市第三人民醫(yī)院→吳井路(福景花園)→吳井路口(吳井路)→五里多村→關(guān)興路口(民航路)→云旅客運(yùn)站→關(guān)上(民航路)→[終到站]'
...................... 共282條線路,其余已省略
3.存儲過程
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[busSearch]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[busSearch]
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_NULLS ON
GO
ALTER proc busSearch
@sta1 nvarchar(50), @sta2 nvarchar(50)
as
--所有包含起始站點(diǎn)的路線表
create table #tmp1(
r_busname nvarchar(100),
r_st char(30),
r_stoe nvarchar(200),
r_line nvarchar(1200)
)
--所有包含到達(dá)站點(diǎn)的路線表
create table #tmp2(
r_busname nvarchar(100),
r_st char(30),
r_stoe nvarchar(200),
r_line nvarchar(1200)
)
--查找結(jié)果
create table #result(
r_bn1 nvarchar(100),
r_st1 char(30),
r_stoe1 nvarchar(200),
r_line1 nvarchar(1200),
r_station nvarchar(100), --轉(zhuǎn)乘站點(diǎn)
r_bn2 nvarchar(100),
r_st2 char(30),
r_stoe2 nvarchar(200),
r_line2 nvarchar(1200)
)
set @sta1=@sta1+'→'
set @sta2=@sta2+'→'
--直達(dá):
insert into #result(r_bn1,r_st1,r_stoe1,r_line1) select * from kmbusline a
where charindex(@sta1,a.line)>0 and charindex(@sta1,a.line)<charindex(@sta2,a.line)
if @@rowcount<=0 begin
--轉(zhuǎn)乘:
insert into #tmp1(r_busname,r_st,r_stoe,r_line)
select a.busname,a.svctime,a.stoe,rtrim(a.line) from kmbusline a
where charindex(@sta1,a.line)>0 --起始線路
insert into #tmp2(r_busname,r_st,r_stoe,r_line)
select a.busname,a.svctime,a.stoe,rtrim(a.line) from kmbusline a
where charindex(@sta2,a.line)>0 --到達(dá)線路
insert into #result
select a.*, c.station, b.*
from #tmp1 a, #tmp2 b, tb_kmbusstations c
where c.station+'→'<>@sta1 and c.station+'→'<>@sta2
and charindex(c.station+'→',a.r_line)>0 and charindex(c.station+'→',b.r_line)>0
and charindex(@sta1,a.r_line)<charindex(c.station+'→',a.r_line)
and charindex(@sta2,b.r_line)>charindex(c.station+'→',b.r_line)
end
select * from #result
drop table #result
drop table #tmp1
drop table #tmp2
GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
--直達(dá):
exec busSearch '公交北市區(qū)車場', '東風(fēng)廣場'
--轉(zhuǎn)乘:
exec busSearch '公交北市區(qū)車場', '西壩'
在站點(diǎn)為928個(gè)、公交路線為282條時(shí),測試轉(zhuǎn)乘查詢時(shí)間一般不超過一秒,可得到30條換乘線路。
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -