当你遇到这样的大问题时,最好的做法是对其进行分区。从技术上讲,所有出发Craiglockhart
的公共汽车最终应达到Sighthill
,并有足够的转移,但我们只限于1次转移(因为这是问题的原因)。
所以基本上,你需要找到一辆从Craiglockhart
出发的公共汽车,以及一辆到达Sighthill
的公共汽车,并且你需要找到它们之间的所有相交站点。
第2个部分是非常容易的(和你有那部分右):
SELECT DISTINCT num , company
FROM route
INNER JOIN stops ON stop = id
WHERE name='Craiglockhart'
和
SELECT DISTINCT num, company AS bus
FROM route
INNER JOIN stops ON stop = id
WHERE name='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)
Relevant SQLFiddle
有一件事值得一提的是,虽然我用“当存在(...)”时,你的练习明确暗示你应该使用自我连接。如果你想学习,我不会给你全部的答案,所以一定要去尝试把它转换成自己的联接;)
那么有什么不行? – leppie 2014-12-02 05:26:58
我发现自己无法解决您的问题,可以通过提及您遇到的错误以及描述您的表结构来更加简明地解释问题。精明? – 2014-12-02 05:33:01