Правда ли, что использование INNER JOIN после любого OUTER JOIN по существу аннулирует эффекты OUTER JOIN? - PullRequest
2 голосов
/ 11 марта 2019

Другими словами, для вложенного / множественного JOIN оператора SQL можно с уверенностью сказать, что всегда следует сначала использовать INNER JOIN (либо поставить его в верхней строке, либо использовать скобки для первого INNER JOIN twoтаблицы) и убедитесь, что он предшествует любым OUTER JOIN (LEFT, RIGHT, FULL)?


Насколько я понимаю, совпадающие столбцы (например, столбец первичного ключа и столбец внешнего ключа) обычно не имеют значений NULL.И любые несоответствующие строки, включая NULL из результата OUTER JOIN, будут удалены, если INNER JOIN -обнаружены другой таблицей, просто потому, что ничто не будет соответствовать NULL !!

(Кстати, я никогда не СОЕДИНЯЛСЯ никакими двумя таблицами, использующими столбцы, у которых есть NULL, поэтому я бы не стал комментировать, будет ли значение NULL совпадать со значением NULL при INNER JOIN -ing таблицах. По крайней мере, этобыло бы крайне редко, я думаю)

Ответы [ 3 ]

3 голосов
/ 11 марта 2019

Последующее внутреннее объединение будет «по существу недействительным» для внешнего объединения, только если для условия внутреннего соединения ON требуется наличие строк, которые должны быть необязательными. В этом случае изменение порядка объединения не будет работать или не поможет; скорее единственное исправление состоит в том, чтобы изменить внутреннее соединение на соответствующее внешнее соединение.

Так, например, это прекрасно работает:

    SELECT *
      FROM person
 LEFT JOIN address
        ON person.address_id = address.id
INNER JOIN email
        ON person.email_id = email.id

и эквивалентно тому, что вы получите, если переместите левое внешнее соединение (строки 3–4) после внутреннего соединения (строки 5–6); тогда как это не работает, как задумано:

    SELECT *
      FROM person
 LEFT JOIN address
        ON person.address_id = address.id
INNER JOIN city
        ON address.city_id = city.id

потому что второе предложение ON может быть выполнено только тогда, когда address.city_id не нуль. (В этом случае правое исправление заключается в замене внутреннего соединения на левое внешнее соединение.)

Тем не менее, я согласен с Гордоном Линоффом в том, что, как правило, лучше всего размещать ваши внутренние соединения перед вашими левыми внешними соединениями; это связано с тем, что внутренние объединения обычно указывают на более «существенные» ограничения, поэтому такой порядок обычно более читабелен. (И я согласен с Гордоном Линоффом и Шоном, что правильных внешних объединений обычно лучше избегать.)

2 голосов
/ 11 марта 2019

Хорошее общее правило - начинать с внутренних объединений, а затем следовать left join с. right join s практически никогда не нужны, а full join s - особый случай. Это в основном то, как я пишу запросы.

Однако это зависит от условий join. Поэтому, хотя я думаю, что приведенные выше правила являются разумными и достаточными для написания практически любого запроса, возможно написать запросы с внутренними объединениями после внешних объединений.

1 голос
/ 12 марта 2019

Нет понятия, что нужно делать что-то в определенном порядке. Есть последствия конкретного выбора выражения.

Узнайте, что left join on возвращает: inner join on строки плюс несопоставленные строки левой таблицы, расширенные нулями. Всегда знайте, что inner join вы хотите, как часть left join. inner join on или where, для которого требуется, чтобы правый столбец таблицы был ненулевым после того, как left join on удаляет все строки, расширенные нулями, то есть оставляет только свои строки inner join on, т. Е. «Превращает внешнее соединение во внутреннее соединение». Вы говорите об этом.

Тебе не нужно беспокоиться об этом. Просто сосредоточьтесь на написании запросов, которые возвращают то, что вы хотите. Ваш вопрос похож на вопрос: должен ли я избегать деления на ноль, поскольку он не определен, или добавления нуля, потому что он ничего не делает? Почему бы вам, так как он не делает то, что вы хотите? Если вы пишете неправильные запросы, узнайте, что делают операторы. Есть ли эмпирическое правило для построения запроса SQL из понятного человеку описания?

PS Моя характеристика left join &, когда его ноль-расширенные строки отбрасываются, фокусируется на ассоциированном inner join, на on в целом и на требовании, чтобы правые столбцы таблицы были нулевыми. Ваш выбор организации запчастей вводит вас в заблуждение и мешает вам. 1. Любые две таблицы могут быть join ed on любым условием. PK - FK равенство - это особый случай. (PK s & FK s не нужны для запроса. Однако они подразумевают определенные ограничения на входы и результаты.) FK & unique столбцы и другие столбцы могут иметь нулевые значения на входе. PK означает unique not null. 2. «совпадающие столбцы» и «ничто не будет соответствовать NULL» перепутаны, потому что это строки или пары строк, которые соответствуют или не совпадают, для всего условия on. 3. «любые несоответствующие строки, включая NULL из результата OUTER JOIN, будут удалены, когда они INNER JOIN» - нет, это зависит от всего условия on или where. 4. «это было бы крайне редко» - не имеет значения; либо что-то может случиться, либо это не может произойти.

...