Как я могу объединить две таблицы (обе получены из self join), чтобы создать третью таблицу? - PullRequest
0 голосов
/ 28 января 2019

Я пытаюсь решить вопрос https://sqlzoo.net/wiki/Self_join, Сам присоединяется к Вопросу № 10, в частности, который говорит, что:

Найдите маршруты с участием двух автобусов, которые могут идти из Крейглокхарта в Лошенд.Показать автобус №и компания для первого автобуса, название остановки для трансфера, и автобус №.и компания для второй шины. '.

У меня есть мой код, и почему-то он выдает ошибку, в которой говорится:

ДУБЛИРОВАНИЕ имя столбца' 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 голосов
/ 28 января 2019

Прежде всего, вы сделали это: 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
0 голосов
/ 29 января 2019

Вот решение, помеченное как «Правильный ответ» sqlzoo.

Оно работает, сначала выбирая все линии, которые останавливаются в Крейглокхарте, и, с другой стороны, все те, которые останавливаются в Лоченде.Для каждого из этих поисков требуется два соединения (остановки + маршрут).

Наконец, запрос находит все остановки, принадлежащие обеим линиям, используя специальное соединение с условиями EXISTS.

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'
0 голосов
/ 28 января 2019

О 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

или даже лучше - не ленитесь инапишите каждое нужное поле по имени

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...