2014-09-17 4 views
3

Я немного удивлен тем, что эти два запроса дают разные результаты:SQL Внутренние соединения внутри Внешних объединений; Вложение Alters Результаты

Первый запрос:

SELECT a.number, a.name , b.* 
FROM Atable a 
LEFT OUTER JOIN Btable b 
JOIN Ctable c ON c.number = b.number 
ON b.number = a.number 
ORDER BY a.number; 

Второй запрос:

SELECT a.number, a.name , b.* 
FROM Atable a 
LEFT OUTER JOIN Btable b ON b.number = a.number 
JOIN Ctable c ON c.number = b.number 
ORDER BY a.number 

Я ожидаю, что оба из них вернет результаты, которые делает первый запрос. Первый запрос возвращает каждую строку из TableA; однако неожиданно вторая строка возвращает результаты таблицы TableA, если они также существуют в TableC.

Почему соединение от C до B ограничивает таблицу A во втором запросе, но не в первом запросе?

Спасибо!

+3

Это то же самое, что и почему (A + B) * C отличается от A + (B * C) – Serpiton

ответ

3

Ваш первый запрос, с круглые скобки, чтобы выяснить, как он обрабатывается:

SELECT a.number, a.name , b.* 
FROM Atable a LEFT OUTER JOIN 
    (Btable b JOIN 
     Ctable c 
     ON c.number = b.number 
    ) ON b.number = a.number 
ORDER BY a.number; 

Имея два on положения подряд сбивает с толку, поэтому круглые скобки помогают. Это дает понять, что вы сохраняете все строки из первой таблицы.

Второй запрос:

SELECT a.number, a.name , b.* 
FROM (Atable a LEFT OUTER JOIN 
     Btable b 
     ON b.number = a.number 
    ) JOIN 
    Ctable c 
    ON c.number = b.number 
ORDER BY a.number; 

Вы внутреннее присоединение результат первого соединения. Следовательно, в набор результатов попадают только строки, которые соответствуют.

Когда вы делаете несколько объединений, я рекомендую использовать left join для всех соединений. Смешивание внутреннего и внешнего соединений может привести к путанице.

+0

Спасибо, Гордон. Ваше размещение круглых скобок помогает ему иметь смысл. Проведя некоторое исследование порядка обработки запросов, он щелкает намного лучше. Ценить это! – Eluros

Смежные вопросы