Mysql 找出两辆公共汽车从A到B的路线

Mysql 找出两辆公共汽车从A到B的路线,mysql,sql,Mysql,Sql,来自sqlzoo的SQL中的问题: 找到从Craiglockhart到Sighthill的两辆公交车的路线。 显示第一辆车的车号和公司,以及换乘站的名称, 还有第二辆车的车号和公司 这是我找到的代码,但是它不起作用: SELECT DISTINCT a.num, a.company, trans1.name , c.num, c.company FROM route a JOIN route b ON (a.company = b.company AND

来自sqlzoo的SQL中的问题: 找到从Craiglockhart到Sighthill的两辆公交车的路线。 显示第一辆车的车号和公司,以及换乘站的名称, 还有第二辆车的车号和公司

这是我找到的代码,但是它不起作用:

    SELECT DISTINCT  a.num, a.company, 
             trans1.name ,  c.num,  c.company
FROM route a JOIN route b
ON (a.company = b.company AND a.num = b.num)
JOIN ( route c JOIN route d ON (c.company = d.company AND c.num= d.num))
JOIN stops start ON (a.stop = start.id)
JOIN stops trans1 ON (b.stop = trans1.id)
JOIN stops trans2 ON (c.stop = trans2.id)
JOIN stops end ON (d.stop =  end.id)
WHERE  start.name = 'Craiglockhart' AND end.name = 'Sighthill'
            AND  trans1.name = trans2.name 
ORDER BY a.num ASC , trans1.name

我假设一条路线由一个起点(即
pos
属性)和一个终点(即
stop
属性)组成。希望这能为你指明正确的方向。外部查询获取在Craiglockhart中开始的所有路由,内部查询获取在Sighthill中结束的所有路由,然后在第一个路由的结束与第二个路由的开始相同的位置加入这两个路由

    SELECT r1.Num     AS FirstBusNo,
           r1.Company AS FirstBusCompany,
           Stops.Name AS Transfer,
           r2.Num     AS SecondBusNo, 
           r2.Company AS SecondBusCompany
      FROM Route r1
INNER JOIN Stops trans 
        ON r1.Stop = trans.Id
INNER JOIN ( SELECT Num, Company, Pos
             FROM Route, Stops
             WHERE Id = stop
             AND Name = 'Sighthill' ) r2
        ON r1.stop = r2.pos
     WHERE Stops.Name = 'Craiglockhart';

我假设一条路线由一个开始(即
pos
属性)和一个结束(即
stop
属性)组成。希望这能为你指明正确的方向。外部查询获取在Craiglockhart中开始的所有路由,内部查询获取在Sighthill中结束的所有路由,然后在第一个路由的结束与第二个路由的开始相同的位置加入这两个路由

    SELECT r1.Num     AS FirstBusNo,
           r1.Company AS FirstBusCompany,
           Stops.Name AS Transfer,
           r2.Num     AS SecondBusNo, 
           r2.Company AS SecondBusCompany
      FROM Route r1
INNER JOIN Stops trans 
        ON r1.Stop = trans.Id
INNER JOIN ( SELECT Num, Company, Pos
             FROM Route, Stops
             WHERE Id = stop
             AND Name = 'Sighthill' ) r2
        ON r1.stop = r2.pos
     WHERE Stops.Name = 'Craiglockhart';

当您遇到这样的大问题时,最好的做法是对其进行分区。从技术上讲,所有离开Craiglockhart的公交车最终都应该到达Sighthill,并且有足够的换乘次数,但我们将限制自己只能换乘一次(因为问题就是这样表述的)

因此,基本上,你需要找到一辆从Craiglockhart出发的巴士和一辆到达Sighthill的巴士,你需要找到这两辆车之间的所有交叉站

前两个部分非常简单(这一部分你做对了):

从那里,您可以看到一张从Craiglockhart出发的所有公交车和到达Sighthill的所有公交车的列表。你唯一剩下的问题是找到这两个相交的地方

解决方案的初始部分同样简单;您需要获取2辆公交车的名称以及站点名称

SELECT DISTINCT  r1.num as NoFrom, r1.company CoFrom, name,r2.num as NoTo, r2.company CoTo
这意味着您必须查询至少3个表

FROM stops
INNER JOIN route r1 ON r1.stop = id
INNER JOIN route r2 ON r2.stop = id
现在,您收集了所有可能传输的列表,您只需要过滤掉无用的传输。一种次优的方法是这样:

WHERE exists(
    SELECT 1
    FROM route r3 
    INNER JOIN stops s1 ON r3.stop = s1.id
    WHERE s1.name='Craiglockhart' AND r3.num = r1.num AND r3.company = r1.company)

AND exists(
    SELECT 1
    FROM route r4 
    INNER JOIN stops s2 ON r4.stop = s2.id
    WHERE s1.name='Sighthill' AND r4.num = r2.num AND r4.company = r2.company)
因此,基本上一种方法是:

SELECT DISTINCT r1.num as NoFrom, r1.company CoFrom, name, r2.num as NoTo, r2.company CoTo
FROM stops
INNER JOIN route r1 ON r1.stop = id
INNER JOIN route r2 ON r2.stop = id
WHERE exists(
    SELECT 1
    FROM route r3 
    INNER JOIN stops s1 ON r3.stop = s1.id
    WHERE s1.name='Craiglockhart' AND r3.num = r1.num AND r3.company = r1.company)
AND exists(
    SELECT 1
    FROM route r4 
    INNER JOIN stops s2 ON r4.stop = s2.id
    WHERE s2.name='Sighthill' AND r4.num = r2.num AND r4.company = r2.company)


但值得注意的是,当您的练习明确暗示您应该使用自联接时,我使用了“WHERE EXISTS(…)”。如果你想学习,我不会给你完整的答案,所以试着把它转换成自连接;)

当您遇到这样的大问题时,最好的做法是对其进行分区。从技术上讲,所有离开Craiglockhart的公交车最终都应该到达Sighthill,并且有足够的换乘次数,但我们将限制自己只能换乘一次(因为问题就是这样表述的)

因此,基本上,你需要找到一辆从Craiglockhart出发的巴士和一辆到达Sighthill的巴士,你需要找到这两辆车之间的所有交叉站

前两个部分非常简单(这一部分你做对了):

从那里,您可以看到一张从Craiglockhart出发的所有公交车和到达Sighthill的所有公交车的列表。你唯一剩下的问题是找到这两个相交的地方

解决方案的初始部分同样简单;您需要获取2辆公交车的名称以及站点名称

SELECT DISTINCT  r1.num as NoFrom, r1.company CoFrom, name,r2.num as NoTo, r2.company CoTo
这意味着您必须查询至少3个表

FROM stops
INNER JOIN route r1 ON r1.stop = id
INNER JOIN route r2 ON r2.stop = id
现在,您收集了所有可能传输的列表,您只需要过滤掉无用的传输。一种次优的方法是这样:

WHERE exists(
    SELECT 1
    FROM route r3 
    INNER JOIN stops s1 ON r3.stop = s1.id
    WHERE s1.name='Craiglockhart' AND r3.num = r1.num AND r3.company = r1.company)

AND exists(
    SELECT 1
    FROM route r4 
    INNER JOIN stops s2 ON r4.stop = s2.id
    WHERE s1.name='Sighthill' AND r4.num = r2.num AND r4.company = r2.company)
因此,基本上一种方法是:

SELECT DISTINCT r1.num as NoFrom, r1.company CoFrom, name, r2.num as NoTo, r2.company CoTo
FROM stops
INNER JOIN route r1 ON r1.stop = id
INNER JOIN route r2 ON r2.stop = id
WHERE exists(
    SELECT 1
    FROM route r3 
    INNER JOIN stops s1 ON r3.stop = s1.id
    WHERE s1.name='Craiglockhart' AND r3.num = r1.num AND r3.company = r1.company)
AND exists(
    SELECT 1
    FROM route r4 
    INNER JOIN stops s2 ON r4.stop = s2.id
    WHERE s2.name='Sighthill' AND r4.num = r2.num AND r4.company = r2.company)


但值得注意的是,当您的练习明确暗示您应该使用自联接时,我使用了“WHERE EXISTS(…)”。如果你想学习,我不会给你完整的答案,所以试着把它转换成自连接;)

找到从Craiglockhart到Lochend的两辆公交车的路线。 显示第一辆车的车号和公司,以及换乘站的名称, 还有第二辆车的车号和公司。 提示: 自行加入两次,找到访问Craiglockhart和Lochend的巴士,然后加入匹配站点的巴士

SELECT DISTINCT one.num as FirstBus, one.company as FirstComp, one.name as Transfer, two.num as SecBus, two.company as SecComp

FROM

    (select distinct a.num, a.company, yy.name
     from route a join route b on (a.company=b.company and a.num=b.num) 
                  join stops xx on (xx.id=a.stop) 
                  join stops yy on (yy.id=b.stop)
     where xx.name='Craiglockhart' and yy.name<>'Lochend'
     ) AS one

JOIN

    (select distinct c.num, d.company, mm.name
     from route c join route d on (c.company=d.company and c.num=d.num) 
                  join stops mm on (mm.id=c.stop) 
                  join stops nn on (nn.id=d.stop)
     where mm.name <> 'Craiglockhart' and nn.name='Lochend'
     ) AS two

ON (two.name=one.name)
Select first.num, first.company, first.name, second.num, second.company
From
    (Select Distinct a.num, a.company, stopb.name
    From route a JOIN route b ON (a.num=b.num AND a.company=b.company)
                 JOIN stops stopa ON stopa.id=a.stop
                 JOIN stops stopb ON stopb.id=b.stop
    Where stopa.name='Craiglockhart') first
JOIN
    (Select Distinct a.num, a.company, stopa.name
    From route a JOIN route b ON (a.num=b.num AND a.company=b.company)
                 JOIN stops stopa ON stopa.id=a.stop
                 JOIN stops stopb ON stopb.id=b.stop
    Where stopb.name='Lochend') second
Where first.name=second.name
选择DISTINCT one.num作为FirstBus,选择one.company作为FirstComp,选择one.name作为Transfer,选择two.num作为SecBus,选择two.company作为SecComp
从…起
(选择不同的a.num、a.company、yy.name
从路由a加入路由b on(a.company=b.company和a.num=b.num)
连接站点xx on(xx.id=a.stop)
连接站点yy on(yy.id=b.stop)
其中xx.name='Craiglockhart'和yy.name'Lochend'
)作为一个整体
参加
(选择不同的c.num、d.company、mm.name
从路由c加入路由d on(c.company=d.company和c.num=d.num)
连接止动块mm on(mm.id=c.stop)
连接停止nn on(nn.id=d.stop)
其中mm.name'Craiglockhart'和nn.name='Lochend'
)两岁
ON(两个.name=一个.name)
逻辑: 1.为那些有“Craiglockhart”但没有“Lochend”的人找到num和公司; 2.为那些有“Lochend”但没有“Craiglockhart”的人找到num和公司; 3.从上面两个表中找到共享的站点——使用表“stops”作为链接; 4.根据需要显示。
希望有帮助

找到从Craiglockhart到Lochend的两辆公交车的路线。 显示第一辆车的车号和公司,以及换乘站的名称, 还有第二辆车的车号和公司。 提示: 自行加入两次,找到访问Craiglockhart和Lochend的巴士,然后加入匹配站点的巴士

SELECT DISTINCT one.num as FirstBus, one.company as FirstComp, one.name as Transfer, two.num as SecBus, two.company as SecComp

FROM

    (select distinct a.num, a.company, yy.name
     from route a join route b on (a.company=b.company and a.num=b.num) 
                  join stops xx on (xx.id=a.stop) 
                  join stops yy on (yy.id=b.stop)
     where xx.name='Craiglockhart' and yy.name<>'Lochend'
     ) AS one

JOIN

    (select distinct c.num, d.company, mm.name
     from route c join route d on (c.company=d.company and c.num=d.num) 
                  join stops mm on (mm.id=c.stop) 
                  join stops nn on (nn.id=d.stop)
     where mm.name <> 'Craiglockhart' and nn.name='Lochend'
     ) AS two

ON (two.name=one.name)
Select first.num, first.company, first.name, second.num, second.company
From
    (Select Distinct a.num, a.company, stopb.name
    From route a JOIN route b ON (a.num=b.num AND a.company=b.company)
                 JOIN stops stopa ON stopa.id=a.stop
                 JOIN stops stopb ON stopb.id=b.stop
    Where stopa.name='Craiglockhart') first
JOIN
    (Select Distinct a.num, a.company, stopa.name
    From route a JOIN route b ON (a.num=b.num AND a.company=b.company)
                 JOIN stops stopa ON stopa.id=a.stop
                 JOIN stops stopb ON stopb.id=b.stop
    Where stopb.name='Lochend') second
Where first.name=second.name
选择DISTINCT one.num作为FirstBus,选择one.company作为FirstComp,选择one.name作为Transfer,选择two.num作为FirstComp