2016-03-21 2 views
6

Я использовал это для лет, так что пришло время его полностью понять. Предположим, что запрос, как это:Несколько LEFT JOINs - что такое «левая» таблица?

SELECT 
    * 
FROM a 
LEFT JOIN b ON foo... 
LEFT JOIN c ON bar... 

documentation говорит нам, что

T1 { [INNER] | { LEFT | RIGHT | FULL } [OUTER] } JOIN T2 ON boolean_expression

LEFT OUTER JOIN

Во-первых, внутреннее соединение выполняется. Затем для каждой строки в T1, которая не удовлетворяет условию объединения с любой строкой в ​​T2, объединенная строка добавляется с нулевыми значениями в столбцах T2. Таким образом, объединенная таблица всегда имеет по крайней мере одну строку для каждой строки в T1.

Вопрос прост: что такое T1 в этом случае? Это a? Или это a LEFT JOIN b ON foo? (или, то же самое?)

+1

Это зависит от того, как вы присоединяетесь к данным (например, foo и bars на вашем примере. Например, если в заявлении «... JOIN c ON bar ...» условия используют таблицы a и b , это будет JOIN b ON foo. –

+2

'(левое соединение b) left join c', то есть сначала' a' является левой таблицей, тогда '(левое соединение b)' является следующей левой таблицей. – jarlh

+0

@ jarlh, если вы напишете это как ответ и дадите ссылки, я его приму. – vektor

ответ

3

FROM пункт разбирает условия слева направо (если не переопределен в скобки). Итак:

FROM a 
LEFT JOIN b 
    ON foo... 
LEFT JOIN c 
    ON bar... 

обрабатывается как:

FROM (
     a 
     LEFT JOIN b 
      ON foo... 
    ) 
LEFT JOIN c 
    ON bar... 

Это объясняется в documentation под join-type части FROM пункта:

Используйте круглые скобки, если необходимо определить порядок вложенности. В отсутствие скобок, JOIN s гнездо слева направо. В любом случае JOIN связывается более плотно, чем запятые, разделяющие FROM -list элементов.

Как следствие, серия LEFT JOIN s хранит все записи в первой упомянутой таблице. Это удобство.

Обратите внимание, что синтаксический анализ предложения FROM тот же, независимо от типа соединения.

+0

Я исказил отступы на ваших примерах, чтобы немного увеличить круглые скобки. Не стесняйтесь возвращаться с моими извинениями, если вы не согласны, что это выглядит лучше. :) – IMSoP

+0

@IMSoP. , , Я довольно не согласен с тем, что он работает лучше, но я не собираюсь менять его. –

0

Ниже приведена краткая операция соединения. SQL - это язык, на котором вы описываете результаты, а не как их получить. Оптимизатор решит, какое соединение нужно делать первым, в зависимости от того, что, по его мнению, будет наиболее эффективным. Вы можете прочитать здесь некоторую информацию
https://community.oracle.com/thread/2428634?tstart=0
Я думаю, он работает так же для PostgreSQL

+0

Не могли бы вы предоставить некоторые ссылки? – vektor

+0

Сначала извините за неправильный ответ. –

+0

@ Gleboss. , , Семантический порядок (как интерпретируются соединения) не связан с порядком выполнения (как реализуются объединения). Следовательно, вы ответили на другой вопрос. –

0

Это может быть и, в зависимости от того, как вы присоединяетесь данные (с Foo и баров на вашем примере).

Например, если в вашем примере вы хотите присоединиться к a с b и a с c, T1 будет.

Но, если вы намерены присоединиться к a с b и результатом этого с помощью c, тогда T1 будет LEFT JOIN b ON foo.

В последнем случае, будет улучшение по читаемости, если вы пишете так:

(a LEFT JOIN b ON foo) LEFT JOIN c ON bar