【发布时间】:2015-11-10 13:49:53
【问题描述】:
我正在尝试构建一个查询,获取从 A 到 B 的路线。有时可能有直接路线,有时我需要找到交叉点并获取交换路线。目标是让一个人从 A 到 B 并给出不同的模式类型和路线。我稍后会添加最短或最佳路线,但现在只是为了获得正确的路线。问题是当我尝试获取相交路线时。不知何故,我觉得应该有一种更简单的方法来完成这项工作。我希望这不是太多的代码。
我认为应该起作用的逻辑是
找到起始路线(Halts 表),如果我们有一个获取 RouteID 和路线编号,如果找不到起始路线,则尝试获取下一个最近的路线。
-
找到终点路线。如果有,请检查起始路线是否在此路线内(这是直接路线),如果是,则获取 RouteID 和路线编号并插入临时表以显示最终路线。
- 如果点 2 没有终点路线,则尝试从起点查找相交路线,并查找是否有任何相交的路线,如果是,则获取该路线 ID 和路线编号。从相交路线尝试是否可以到达终点路线
this is where I got lost as there can be more than one intersecting route
- 如果点 2 没有终点路线,则尝试从起点查找相交路线,并查找是否有任何相交的路线,如果是,则获取该路线 ID 和路线编号。从相交路线尝试是否可以到达终点路线
RouteTypes 表
此表有不同的路线类型,如城市巴士、长途巴士、本地火车、长途火车、国内航班、国际航班
CREATE TABLE [dbo].[RouteTypes](
[RouteTypeID] [int] IDENTITY(1,1) NOT NULL,
[ModeTypeID] [int] NOT NULL,
[RouteType] [nvarchar](50) NOT NULL,
CONSTRAINT [PK_RouteTypes] PRIMARY KEY CLUSTERED
(
[RouteTypeID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
模式类型表
此表将包含不同的交通类型,如公共汽车、火车、航班
CREATE TABLE [dbo].[ModeTypes](
[ModeTypeID] [int] IDENTITY(1,1) NOT NULL,
[ModeType] [nvarchar](50) NOT NULL,
[IsEnabled] [bit] NOT NULL,
CONSTRAINT [PK_ModeTypes] PRIMARY KEY CLUSTERED
(
[ModeTypeID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
暂停表格
此表将保存所有暂停,并且是暂停的主表
CREATE TABLE [dbo].[Halts](
[HaltID] [int] IDENTITY(1,1) NOT NULL,
[Halt] [nvarchar](100) NOT NULL
) ON [PRIMARY]
路线表
这个表会有一些路线编号。由于我不太清楚需要在此处添加什么,因此我目前未使用的大多数字段
CREATE TABLE [dbo].[Routes](
[RouteID] [int] IDENTITY(1,1) NOT NULL,
[RouteTypeID] [int] NOT NULL,
[RouteNo] [nvarchar](30) NOT NULL,
[Duration] [nvarchar](30) NULL,
[Distance] [nvarchar](30) NULL,
[OldRouteNo] [nvarchar](30) NULL,
[DaysAvailable] [char](15) NULL,
[IsEnabled] [bit] NOT NULL,
[BeginAt] [time](7) NULL,
[EndAt] [time](7) NULL,
CONSTRAINT [PK_Routes] PRIMARY KEY CLUSTERED
(
[RouteID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
路由暂停表
CREATE TABLE [dbo].[RouteHalts](
[RouteHaltID] [int] IDENTITY(1,1) NOT NULL,
[RouteID] [int] NOT NULL,
[FirstLastHalt] [char](1) NULL,
[HaltNo] [smallint] NULL,
[HaltID] [int] NOT NULL,
CONSTRAINT [PK_RouteHalts] PRIMARY KEY CLUSTERED
(
[RouteHaltID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
我正在使用存储过程,这就是我到目前为止所得到的。当我得到检查路线时,结果有些不正确。
DECLARE @StartingRouteID int;
DECLARE @EndingRouteID int;
DECLARE @CrossRouteHalt nvarchar(100);
CREATE TABLE #TmpStartingRoute
(
ID INT IDENTITY(1,1) NOT NULL,
RouteID int null,
RouteNo nvarchar(60) null,
RouteType nvarchar(100) null,
Duration nvarchar(60) null,
Distance nvarchar(60) null,
DaysAvailable nvarchar(60) null,
Halt nvarchar(100) null,
ModeType nvarchar(100) null
)
CREATE TABLE #TmpStartingHalts
(
ID INT IDENTITY(1,1) NOT NULL,
RouteID int null,
RouteNo nvarchar(60) null,
RouteType nvarchar(100) null,
Duration nvarchar(60) null,
Distance nvarchar(60) null,
DaysAvailable nvarchar(60) null,
Halt nvarchar(100) null,
ModeType nvarchar(100) null
)
CREATE TABLE #TmpEndingRoute
(
ID INT IDENTITY(1,1) NOT NULL,
RouteID int null,
RouteNo nvarchar(60) null,
RouteType nvarchar(100) null,
Duration nvarchar(60) null,
Distance nvarchar(60) null,
DaysAvailable nvarchar(60) null,
Halt nvarchar(100) null,
ModeType nvarchar(100) null
)
CREATE TABLE #TmpEndingHalts
(
ID INT IDENTITY(1,1) NOT NULL,
RouteID int null,
RouteNo nvarchar(60) null,
RouteType nvarchar(100) null,
Duration nvarchar(60) null,
Distance nvarchar(60) null,
DaysAvailable nvarchar(60) null,
Halt nvarchar(100) null,
ModeType nvarchar(100) null
)
CREATE TABLE #TmpRts
(
ID INT IDENTITY(1,1) NOT NULL,
RouteID int null,
Halt nvarchar(100) null,
RouteNo nvarchar(60) null,
RouteType nvarchar(100) null,
ModeType nvarchar(100) null
)
CREATE TABLE #TmpIntersection
(
ID INT IDENTITY(1,1) NOT NULL,
RouteID int null,
Halt nvarchar(100) null,
RouteNo nvarchar(60) null,
RouteType nvarchar(100) null,
ModeType nvarchar(100) null
)
CREATE TABLE #FinalRoute
(
ID INT IDENTITY(1,1) NOT NULL,
RouteID int null,
RouteNo nvarchar(60) null,
Halt nvarchar(100) null,
RouteType nvarchar(100) null,
ModeType nvarchar(100) null
)
-- Check if Starting point exits
IF EXISTS(SELECT 1 FROM RouteHalts where Halt like'%'+ @StartingPoint +'%')
BEGIN
SELECT
@StartingRouteID=R.RouteID
from
ModeTypes M
inner join
RouteTypes RT on M.ModeTypeID=RT.ModeTypeID
inner join
Routes R on RT.RouteTypeID=R.RouteTypeID
inner join
RouteHalts RH on R.RouteID=RH.RouteID
where
RH.Halt like'%'+ @StartingPoint +'%'
insert into #TmpStartingRoute(RouteID,RouteNo,RouteType,Duration,Distance,DaysAvailable,Halt,ModeType)
SELECT
R.RouteID, R.RouteNo,RT.RouteType,R.Duration,R.Distance,R.DaysAvailable, RH.Halt,M.ModeType
from
ModeTypes M
inner join
RouteTypes RT on M.ModeTypeID=RT.ModeTypeID
inner join
Routes R on RT.RouteTypeID=R.RouteTypeID
inner join
RouteHalts RH on R.RouteID=RH.RouteID
where
RH.Halt like'%'+ @StartingPoint +'%'
order by
R.RouteNo,RH.HaltNo
-- Insert halts of starting routes
insert into #TmpStartingHalts(RouteID,RouteNo,RouteType,Duration,Distance,DaysAvailable,Halt,ModeType)
SELECT
R.RouteID, R.RouteNo,RT.RouteType,R.Duration,R.Distance,R.DaysAvailable, RH.Halt,M.ModeType
from
ModeTypes M
inner join
RouteTypes RT on M.ModeTypeID=RT.ModeTypeID
inner join
Routes R on RT.RouteTypeID=R.RouteTypeID
inner join
RouteHalts RH on R.RouteID=RH.RouteID
where
RH.RouteID=@StartingRouteID and RH.Halt not like'%'+ @StartingPoint +'%'
order by
R.RouteNo,RH.HaltNo
END
ELSE
-- Find the closest locaton of the starting point
BEGIN
RAISERROR('No Routes Available', 16, 2)
RETURN
END
-- Check if Ending point exits within the start route to get the direct route
IF EXISTS(SELECT 1 FROM RouteHalts R INNER JOIN #TmpStartingRoute SR on R.RouteID=SR.RouteID
where R.Halt like'%'+ @EndingPoint +'%')
BEGIN
print 'In End route exists within starting route'
SELECT
@EndingRouteID= R.RouteID
from
ModeTypes M
inner join
RouteTypes RT on M.ModeTypeID=RT.ModeTypeID
inner join
Routes R on RT.RouteTypeID=R.RouteTypeID
inner join
RouteHalts RH on R.RouteID=RH.RouteID
INNER JOIN
#TmpStartingRoute SR on R.RouteID=SR.RouteID
where
RH.Halt like'%'+ @EndingPoint +'%'
insert into #TmpEndingRoute(RouteID,RouteNo,RouteType,Duration,Distance,DaysAvailable,Halt,ModeType)
SELECT
R.RouteID,R.RouteNo, RT.RouteType,R.Duration,R.Distance,R.DaysAvailable, RH.Halt,M.ModeType
from
ModeTypes M
inner join
RouteTypes RT on M.ModeTypeID=RT.ModeTypeID
inner join
Routes R on RT.RouteTypeID=R.RouteTypeID
inner join
RouteHalts RH on R.RouteID=RH.RouteID
INNER JOIN
#TmpStartingRoute SR on R.RouteID=SR.RouteID
where
RH.Halt like'%'+ @EndingPoint +'%'
order by
R.RouteNo,RH.HaltNo
-- Insert all halts of ending route
insert into #TmpEndingHalts(RouteID,RouteNo,RouteType,Duration,Distance,DaysAvailable,Halt,ModeType)
SELECT
R.RouteID,R.RouteNo, RT.RouteType,R.Duration,R.Distance,R.DaysAvailable, RH.Halt,M.ModeType
from
ModeTypes M
inner join
RouteTypes RT on M.ModeTypeID=RT.ModeTypeID
inner join
Routes R on RT.RouteTypeID=R.RouteTypeID
inner join
RouteHalts RH on R.RouteID=RH.RouteID
where
RH.RouteID=@EndingRouteID and RH.Halt not like'%'+ @EndingPoint +'%'
order by
R.RouteNo,RH.HaltNo
delete from #TmpStartingHalts where RouteID not in (select RouteID from #TmpEndingRoute)
delete from #TmpStartingRoute where RouteID not in (select RouteID from #TmpEndingRoute)
select * from #TmpEndingRoute
END
ELSE
-- Find the closest locaton of the starting point
BEGIN
print 'In End route does NOT exists within starting route'
SELECT
@EndingRouteID= R.RouteID
from
ModeTypes M
inner join
RouteTypes RT on M.ModeTypeID=RT.ModeTypeID
inner join
Routes R on RT.RouteTypeID=R.RouteTypeID
inner join
RouteHalts RH on R.RouteID=RH.RouteID
where
RH.Halt like'%'+ @EndingPoint +'%'
insert into #TmpEndingRoute(RouteID,RouteNo,RouteType,Duration,Distance,DaysAvailable,Halt,ModeType)
SELECT
R.RouteID,R.RouteNo, RT.RouteType,R.Duration,R.Distance,R.DaysAvailable, RH.Halt,M.ModeType
from
ModeTypes M
inner join
RouteTypes RT on M.ModeTypeID=RT.ModeTypeID
inner join
Routes R on RT.RouteTypeID=R.RouteTypeID
inner join
RouteHalts RH on R.RouteID=RH.RouteID
where
RH.Halt like'%'+ @EndingPoint +'%'
order by
R.RouteNo,RH.HaltNo
-- Insert all halts of ending route
insert into #TmpEndingHalts(RouteID,RouteNo,RouteType,Duration,Distance,DaysAvailable,Halt,ModeType)
SELECT
R.RouteID,R.RouteNo, RT.RouteType,R.Duration,R.Distance,R.DaysAvailable, RH.Halt,M.ModeType
from
ModeTypes M
inner join
RouteTypes RT on M.ModeTypeID=RT.ModeTypeID
inner join
Routes R on RT.RouteTypeID=R.RouteTypeID
inner join
RouteHalts RH on R.RouteID=RH.RouteID
where
RH.RouteID=@EndingRouteID and RH.Halt not like'%'+ @EndingPoint +'%'
order by
R.RouteNo,RH.HaltNo
END
-- Get the intersection Routes
insert into #TmpRts(RouteID,Halt,RouteNo,RouteType,ModeType)
select RH.RouteID,RH.halt,TER.RouteNo,TER.RouteType,TER.ModeType
from
RouteHalts RH
INNER JOIN
#TmpEndingRoute TER on RH.RouteID=TER.RouteID
-- Get the intersection Halt
IF EXISTS( select 1 from RouteHalts RH INNER JOIN #TmpRts TER on TER.Halt=RH.Halt
where RH.RouteID in (select RouteID from #TmpStartingRoute))
begin
print 'in exists'
select
@CrossRouteHalt= TER.Halt
from
RouteHalts RH
INNER JOIN
#TmpRts TER on TER.Halt=RH.Halt
where RH.RouteID in (select RouteID from #TmpStartingRoute)
-- Insert into #TmpIntersection
insert into #TmpIntersection(RouteID,Halt,RouteNo,RouteType,ModeType)
select RH.RouteID,RH.Halt,RouteNo,RouteType,ModeType
from
RouteHalts RH
INNER JOIN
#TmpRts TER on TER.Halt=RH.Halt
where RH.RouteID in (select RouteID from #TmpStartingRoute)
end
-- If no intersection halt exsits then try to get the matching routes from the starting point halts
IF not EXISTS( select 1 from RouteHalts RH INNER JOIN #TmpRts TER on TER.Halt=RH.Halt
where RH.RouteID in (select RouteID from #TmpStartingRoute))
begin
print 'in not exists'
insert into #TmpRts(RouteID,Halt,RouteNo)
select distinct RH.RouteID,RH.halt,TSR.RouteNo
from
RouteHalts RH
INNER JOIN
#TmpStartingHalts TSR on RH.Halt=TSR.Halt
-- Update the Route type to show the current route type of the connecting routes
update TER
set TER.RouteType = RT.RouteType, TER.ModeType=MT.ModeType
from #TmpRts TER
INNER JOIN Routes R on TER.RouteID=R.RouteID
inner join
RouteTypes RT on R.RouteTypeID=RT.RouteTypeID
inner join
ModeTypes MT on RT.ModeTypeID=MT.ModeTypeID
select
@CrossRouteHalt= TSR.Halt
from
RouteHalts RH
INNER JOIN
#TmpRts TSR on TSR.Halt=RH.Halt
where RH.RouteID in (select RouteID from #TmpStartingHalts)
-- Insert into #TmpIntersection
insert into #TmpIntersection(RouteID,Halt,RouteNo,RouteType,ModeType)
select RH.RouteID,RH.Halt,RouteNo,RouteType,ModeType
from
RouteHalts RH
INNER JOIN
#TmpRts TSR on TSR.Halt=RH.Halt
where RH.RouteID in (select RouteID from #TmpStartingHalts)
end
/*
Insert all data in to #FinalRoute
*/
-- Insert the Starting Route record
insert into #FinalRoute(RouteID,Halt,RouteNo,RouteType,ModeType)
select RouteID,Halt,RouteNo,RouteType,ModeType from #TmpStartingRoute
-- Insert the Intersection Halt
insert into #FinalRoute(Halt)
select @CrossRouteHalt
-- Get the new Starting point
delete from #TmpRts where routeid in (select routeid from #TmpStartingRoute)
select RH.RouteID,RH.halt,R.RouteNo,TER.RouteType,TER.ModeType
into #TmpNewStartingPoint
from
RouteHalts RH
INNER JOIN
#TmpRts TER on RH.RouteID=TER.RouteID and TER.RouteID not in (select routeid from #TmpEndingRoute)
inner join Routes R on TER.RouteID=R.RouteID and TER.RouteID not in (select routeid from #TmpEndingRoute)
/*
Insert all data in to #FinalRoute
*/
-- Check if #TmpNewStartingPoint is empty then add the insersection route from #TmpRts else add the data from #TmpNewStartingPoint
IF NOT EXISTS(select 1 from #TmpNewStartingPoint)
BEGIN
print 'in no new starting point'
insert into #FinalRoute(RouteID,Halt,RouteNo,RouteType,ModeType)
select RouteID, Halt,RouteNo,RouteType,ModeType from #TmpRts where Halt=@CrossRouteHalt
END
IF EXISTS(select 1 from #TmpNewStartingPoint)
BEGIN
print 'in new starting point'
insert into #FinalRoute(RouteID,Halt,RouteNo,RouteType,ModeType)
select RouteID,Halt,RouteNo,RouteType,ModeType from #TmpNewStartingPoint where halt in (select halt from #TmpEndingHalts)
END
-- Insert the Ending Route record
insert into #FinalRoute(RouteID,Halt,RouteNo,RouteType,ModeType)
select RouteID,Halt,RouteNo,RouteType,ModeType from #TmpEndingRoute
select * from #FinalRoute
编辑 1 我发现这些链接很有趣,所以在这里添加它
【问题讨论】:
-
这是一个巨大的问题,我们在这里的答案中只能触及表面;因此我的投票“过于广泛”。
-
@AakashM 我还在寻找是否有更简单的方法
标签: sql sql-server database