我正在尝试解决问题https://sqlzoo.net/wiki/Self_join,自我加入第10号问题,具体说:
查找涉及两辆从Craiglockhart到Lochend的巴士的路线。显示巴士号码第一辆巴士的公司和公司,中转站的名称以及巴士号和第二辆巴士的公司。'。
我有我的代码,并且以某种方式给我错误提示:
DUPLICATE列名'num'
这是我的代码:
SELECT * FROM
(SELECT *
FROM route a JOIN route b
ON a.company = b.company AND a.num = b.num
JOIN stops stopa ON (a.stop = stopa.id)
JOIN stops stopb ON (b.stop = stopb.id)
WHERE stopa.name = 'Craiglockhart') big
/* [big] table Gives all buses from
craiglockhart */
JOIN
(SELECT *
FROM route a JOIN route b
ON a.company = b.company AND a.num = b.num
JOIN stops stopa ON (a.stop = stopa.id)
JOIN stops stopb ON (b.stop = stopb.id)
WHERE stopa.name = 'Lochend') small
/*[small] Gives all buses from Lochend */
ON big.b.stop = small.b.stop
/*Trying to join the two tables on the basis of
the matching values from [big].b.stop field with [small].b.stop */
我不确定这是否能达到预期的效果。如果是,这是一种有效的方法吗?如果没有,有人可以帮我写信并向我解释如何运作,谢谢?
答案 0 :(得分:1)
首先,您做到了:ON a.company = b.company AND a.num = b.num
->它为列num
返回相同的值-因此它是重复项。
使用索引-例如a.num
和b.num
:
SELECT a.num
FROM route a JOIN route b
ON a.company = b.company AND a.num = b.num
--OR
SELECT b.num
FROM route a JOIN route b
ON a.company = b.company AND a.num = b.num
ON big.b.stop = small.b.stop
也会抛出错误
正确答案:
SELECT DISTINCT x.num, x.company,x.name,y.num,y.company
FROM (
select a.num as num, a.company as company, stopb.name as name
FROM route a
JOIN route b
ON a.company = b.company AND a.num = b.num
JOIN stops stopa ON (a.stop = stopa.id)
JOIN stops stopb ON (b.stop = stopb.id)
WHERE stopa.name = 'Craiglockhart') x
JOIN
(select a.num as num, a.company as company, stopb.name as name
FROM route a
JOIN route b
ON a.company = b.company AND a.num = b.num
JOIN stops stopa ON (a.stop = stopa.id)
JOIN stops stopb ON (b.stop = stopb.id)
WHERE stopa.name = 'Lochend') y
ON x.name = y.name
ORDER BY x.num
答案 1 :(得分:1)
这是sqlzoo标记为“正确答案”的解决方案。
首先选择在克雷格洛克哈特(Craiglockhart)停靠的所有线路,另一方面,选择在洛兴(Lochend)停靠的所有线路。每个搜索都需要两个JOIN(站点+路线)。
最后,查询使用具有EXISTS条件的特殊JOIN查找属于两条线的所有停靠点。
SELECT
r1.num,
r1.company,
s3.name,
r2.num,
r2.company
FROM
stops s1
INNER JOIN route r1 ON r1.stop = s1.id
INNER JOIN stops s2 ON s2.name = 'Lochend'
INNER JOIN route r2 ON r2.stop = s2.id
INNER JOIN stops s3
ON EXISTS (
SELECT 1
FROM route
WHERE
num = r1.num
AND company = r1.company
AND stop = s3.id
)
AND EXISTS (
SELECT 1
FROM route
WHERE
num = r2.num
AND company = r2.company
AND stop = s3.id
)
WHERE
s1.name = 'Craiglockhart'
答案 2 :(得分:0)
关于DUPLICATE COLUMN num
:
如果是自我加入,您有两组列(包括列num
):一个来自route a
,另一个来自route b
(SELECT * -- double set of columns from table [route]
FROM route a JOIN route b
ON a.company = b.company AND a.num = b.num
您必须用字段名替换*
,同时避免重复字段名
例如
(SELECT a.*
FROM route a JOIN route b
ON a.company = b.company AND a.num = b.num
甚至更好-不要偷懒,按名称写每个需要的字段