如何连接两个表(均来自自连接)以创建第三个表?

时间:2019-01-28 20:07:50

标签: sql mariadb

我正在尝试解决问题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 */

我不确定这是否能达到预期的效果。如果是,这是一种有效的方法吗?如果没有,有人可以帮我写信并向我解释如何运作,谢谢?

3 个答案:

答案 0 :(得分:1)

首先,您做到了:ON a.company = b.company AND a.num = b.num

->它为列num返回相同的值-因此它是重复项。

使用索引-例如a.numb.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

甚至更好-不要偷懒,按名称写每个需要的字段