如何建立多对多关系?

wangxil 2003-10-20 04:34:59
我现在正在做一个公交查询系统,设计了两个表:公交线路表和公交站点表
例如公交线路表以公共汽车号为关键字,那么每路公共汽车对应多个公交站点,且公交站点不固定。而公交站点表中的一个公交站点对应一路或多路公共汽车。
现在我要查询任意两个公交站点之间的最优乘车路线。
请大虾们帮助我设计一下这个数据库关系怎样建立起来,特别是以上两个表的关系怎样建立。
我是一个刚刚涉及数据库编程的菜鸟,请大虾们不吝指教
...全文
136 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
wangxil 2003-10-27
  • 打赏
  • 举报
回复
谢谢大家热情指教
wangxil 2003-10-23
  • 打赏
  • 举报
回复
tjan(安安)兄 :线路站点信息表的列项怎么设计?因为一条线路对应多个站点,而且每条线路的站点数目不一样
啊呀 2003-10-23
  • 打赏
  • 举报
回复
如基本关系数据库设计理论,
我们可以建立中间表存储多对多的关系
具体划分应该根据实际应用中的实体关系来确定
你的问题好像在算法,不是在关系呀

wangxil 2003-10-22
  • 打赏
  • 举报
回复
tjan(安安)兄,你说的太模糊了,能否具体给些指教或者例子
tjan 2003-10-22
  • 打赏
  • 举报
回复
你的需求:公交线路表、公交站点表,多对多关系

我的设计:公交线路信息(线路是唯一的)、公交站点信息(站点是唯一的)、线路站点信息(线路+站点是唯一的)
yeshucheng 2003-10-21
  • 打赏
  • 举报
回复
基本上跟上面的几个大哥说的差不多。象一些多队多的表一定要建立1:N的关系,也就是寻找过度的表
tjan 2003-10-21
  • 打赏
  • 举报
回复
分成两个表,一个是多对一,一个是一对多。
qdubit 2003-10-20
  • 打赏
  • 举报
回复
请参考下面的例子:

--@s记录某个车任意一段(中间不停车)的资料。假设
declare @s table(车号 varchar(10),从 varchar(10),到 varchar(10))
insert @s(车号,从,到)
select '920','重庆南路','西藏南路') union all
select '920','西藏南路','重庆南路') union all
select '920','西藏南路','小北门') union all
select '920','小北门','西藏南路') union all
select '920','小北门','老西门') union all
select '920','老西门','小北门')
--请在上面继续补充其它路车资料

--假设查找从@from到@to的路线
--1.不需要转车
select distinct 车号,@from as 上车,@to as 下车
from @t as a
inner join @t as b on b.车号=a.车号
where a.从=@from and b.到=@to
--2.需要转一次车
select distinct 车号,@from as 上车,@to as 下车
from @t as a
inner join @t as b on b.车号=a.车号
inner join @t as c on b.到=c.从
inner join @t as d on d.车号=c.车号
where a.从=@from and d.到=@to and b.车号<>c.车号
--2.需要转两次车
select distinct 车号,@from as 上车,@to as 下车
from @t as a
inner join @t as b on b.车号=a.车号
inner join @t as c on b.到=c.从
inner join @t as d on d.车号=c.车号
inner join @t as e on e.到=d.从
inner join @t as f on f.车号=e.车号
where a.从=@from and d.到=@to and b.车号<>c.车号 and e.车号<>d.车号
--综合以上结果
select distinct 车号,@from as 上车,@to as 下车
from @t as a
inner join @t as b on b.车号=a.车号
where a.从=@from and b.到=@to
union all
select distinct 车号,@from as 上车,@to as 下车
from @t as a
inner join @t as b on b.车号=a.车号
inner join @t as c on b.到=c.从
inner join @t as d on d.车号=c.车号
where a.从=@from and d.到=@to and b.车号<>c.车号
select distinct 车号,@from as 上车,@to as 下车
from @t as a
inner join @t as b on b.车号=a.车号
inner join @t as c on b.到=c.从
inner join @t as d on d.车号=c.车号
inner join @t as e on e.到=d.从
inner join @t as f on f.车号=e.车号
where a.从=@from and d.到=@to and b.车号<>c.车号 and e.车号<>d.车号
lysoon 2003-10-20
  • 打赏
  • 举报
回复
分解成一对多
double22822 2003-10-20
  • 打赏
  • 举报
回复
公交线路表主要内容:线路号,方向(由起始站to终点站),沿途各站(从起始站到终点站的站点编号(顺序写,中间用特殊的分隔符分隔,如"||"))...
公交站点表: 站点编号,经过车号,公车的行使方向...
公车表:线路号,车型,绝对票价,分站点,分站点内票价,跨分站点票价,发车间隔时间,每站间隔大约时间,早车...
wangxil 2003-10-20
  • 打赏
  • 举报
回复
我觉得yujohny兄的意见还是没有实际解决问题
wangxil 2003-10-20
  • 打赏
  • 举报
回复
公交车有环形来回的,也有单向的
txlicenhe 2003-10-20
  • 打赏
  • 举报
回复

set nocount on
declare @ table(xl int,zh int,xh int)
insert @ select 8,1,1
union all select 8,2,2
union all select 8,3,3
union all select 6,4,1
union all select 6,3,2
union all select 6,5,3
union all select 7,8,1
union all select 7,5,2
union all select 7,9,3
union all select 7,10,4
union all select 7,11,5
--select xl 线路,zh 站号,xh 序号 from @

--我给出开始站1,结束站9,求需要中转的站!
===================================================================
--我只能先假设你的公交车是来回的。就是非单程的。
declare @start int,@end int
set @start=1
set @end=9

select cast(rtrim(xl)+','+rtrim(zh) as varchar(1000)) as t,xl,zh into #t
from @
where zh=@start

insert #t select A.t+'到'+rtrim(B.xl)+','+rtrim(B.zh),B.xl,B.xh
from #t a,@ B
where a.zh<>b.zh and a.xl=b.xl


while not exists (select 1
from #t
where zh=@end)
and exists (select 1
from #t a,@ B
where a.zh=b.zh
and a.xl<>b.xl
and a.t+'转'+rtrim(B.xl)+','+rtrim(B.zh) not in (select t from #t)
and B.xl not in (select xl from #t))
begin
insert #t select A.t+'转'+rtrim(B.xl)+','+rtrim(B.zh),B.xl,B.zh
from #t a,@ B
where a.zh=b.zh
and a.xl<>b.xl
and a.t+'到'+rtrim(B.xl)+','+rtrim(B.zh) not in (select t from #t)
and B.xl not in (select xl from #t)

insert #t select A.t+'到'+rtrim(B.xl)+','+rtrim(B.zh),B.xl,B.zh
from #t a,@ B
where a.zh<>b.zh
and a.xl=b.xl
and not exists
(select 1 from #t where xl=b.xl and zh=b.zh)
end

select top 1 t from #t where zh=@end order by len(t)

drop table #t

--RESULT:

--8,1到8,3转6,3到6,5转7,5到7,9

txlicenhe 2003-10-20
  • 打赏
  • 举报
回复
参考:
http://expert.csdn.net/Expert/topic/2112/2112123.xml?temp=.9555628

txlicenhe 2003-10-20
  • 打赏
  • 举报
回复

下面是一个飞机转机的代码,和公交转车差不多,
这个代码是以价格最便宜的线路以最优线路选择的,你可以改成最少路程或最小转车.

create table Flight([from] varchar(10),[to] varchar(10),cost varchar(10),airline varchar(10))

insert Flight values('SF','Denver','300','Frontier')
insert Flight values('SF','Denver','350','United')
insert Flight values('Denver','SF','250','United')
insert Flight values('Denver','SF','250','Frontier')
insert Flight values('Denver','Chicago','250','American')
insert Flight values('Chicago','NY','250','Delta')
insert Flight values('Denver','NY','500','American')
insert Flight values('Denver','NY','400','TWA')
insert Flight values('SF','NY','750','United')


select * from flight

TRY:
select dbo.FN_Getline('SF','Chicago','',0,'',0,'')
select dbo.FN_Getline('SF','Denver','',0,'',0,'')
select dbo.FN_Getline('Chicago','SF','',0,'',0,'')

select 569/12345.2333



select charIndex('cost:','[SF-Denver]Cost:300.00')
select right('[SF-Denver]Cost:300.00',10)
select len('[SF-Denver]Cost:300.00')
20-12

select cast(right('[SF-Denver]Cost:300.00',len('[SF-Denver]Cost:300.00')-charindex('Cost:','[SF-Denver]Cost:300.00')-4) as numeric(20,2))


CREATE FUNCTION FN_Getline
(
@InputFrom varchar(100)
,@inputTo varchar(100)
,@bestLine='' varchar(8000)
,@CurrCost=0 numeric(20,2)
,@str='' varchar(8000)
,@minCost=0 numeric(20,2)
)

RETURNS Varchar(8000)
AS
BEGIN

Declare @temTo varchar(100),@temcost Numeric(20,2)
,@str varchar(8000),@cost Numeric(20,2)

if @str='' then @str=@InputFrom

DECLARE Getline CURSOR local FOR --定义游标
SELECT [To],[Cost]
FROM flight
where [from]=@InputFrom

OPEN Getline
FETCH NEXT FROM flight
INTO @temTo,@temcost

WHILE @@FETCH_STATUS = 0
BEGIN
if @bestLine<>'' then
begin
@minCost=cast(right(@bestLine,len(@bestLine)-charindex('Cost:',@bestLine)-5)as numeric(20,2))
end
set @CurrCost=@CurrCost+@temcost
select @Str=@Str+'['+@InputFrom+'-'+@temTo+']'

if @temTo=@inputTo then
begin
if @minCost=0 or @CurrCost<@minCost then
begin
@bestLine=@Str+'Cost:'+cast(@CurrCost as varchar)
@minCost=@CurrCost
Return @bestLine
end
end
if @CurrCost<@minCost
select @bestLine=dbo.FN_GetSubClass (@temTo,@inputTo,@bestLine,@CurrCost,@str,@minCost) --递归,自己调用自己。
else
Return @bestLine


FETCH NEXT FROM flight
INTO @temTo,@temcost

End

CLOSE Getline
DEALLOCATE Getline

Return @bestLine

END




yujohny 2003-10-20
  • 打赏
  • 举报
回复
最好是这样设计表,用三个表化解多对多关系
公交车表:车号、其它资料
路线表:站号、名称…………
中间表:车号、站号……

22,206

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧