В чем разница между «использованием» и «вкл» в соединениях таблиц в MySQL? - PullRequest
12 голосов
/ 16 декабря 2008

Это

... T1 join T2 using(ID) where T2.VALUE=42 ...

так же, как

... T1 join T2 on(T1.ID=T2.ID) where T2.VALUE=42 ...

для всех типов соединений?

Я понимаю using(ID), что это просто сокращение для on(T1.ID=T2.ID). Это правда?


Теперь к другому вопросу:

Это то же самое, что и

... T1 join T2 on(T1.ID=T2.ID and T2.VALUE=42) ...

Я не думаю, что это правда, но почему? Как условия в предложении on взаимодействуют с оператором join против предложения where?

Ответы [ 7 ]

14 голосов
/ 16 декабря 2008

Я не использую синтаксис USING, так как

  1. большинство моих объединений ему не подходит (не совпадает с именем поля, которое сопоставляется, и / или несколько совпадений в объединении) и
  2. не сразу очевидно, к чему это приводит в случае с более чем двумя таблицами

т. Е. При условии 3 таблицы со столбцами 'id' и 'id_2',

T1 JOIN T2 USING(id) JOIN T3 USING(id_2)

1012 * стать *

T1 JOIN T2 ON(T1.id=T2.id) JOIN T3 ON(T1.id_2=T3.id_2 AND T2.id_2=T3.id_2)

или

T1 JOIN T2 ON(T1.id=T2.id) JOIN T3 ON(T2.id_2=T3.id_2)

или что-то еще?

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

Очевидное отличие от WHERE против ON в том, что соединение является внешним:

Если предположить, что T1 с одним полем ID, одна строка содержит значение 1, а T2 с полем ID и VALUE (одна строка, ID = 1, VALUE = 6), то получим:

SELECT T1.ID, T2.ID, T2.VALUE FROM T1 LEFT OUTER JOIN T2 ON(T1.ID=T2.ID) WHERE T2.VALUE=42

не дает строк, так как ГДЕ должно совпадать, тогда как

SELECT T1.ID, T2.ID, T2.VALUE FROM T1 LEFT OUTER JOIN T2 ON(T1.ID=T2.ID AND T2.VALUE=42)

даст одну строку со значениями

1, NULL, NULL

, поскольку ON требуется только для сопоставления соединения, что является необязательным, поскольку является внешним.

10 голосов
/ 16 декабря 2008

Предложение USING является сокращением для равного объединения столбцов, при условии, что столбцы существуют в обеих таблицах с одинаковым именем:

A JOIN B USING (column1)

A JOIN B ON A.column1=B.column1

Вы также можете назвать несколько столбцов, что упрощает объединение составных ключей. Следующие объединения должны быть эквивалентны:

A JOIN B USING (column1, column2)

A JOIN B ON A.column1=B.column1 AND A.column2=B.column2

Обратите внимание, что USING (<columnlist>) необходимо иметь круглые скобки, тогда как ON <expr> не обязательно иметь круглые скобки (хотя символы скобки могут использоваться в <expr>, только они могут быть включены в выражение в любом другом контексте). *

Кроме того, никакие другие таблицы, объединенные в запросе, не могут иметь столбец с таким именем, иначе запрос неоднозначен, и вы должны получить ошибку.

Относительно вашего вопроса о дополнительных условиях, при условии, что вы используете INNER JOIN, он должен логически давать тот же результат запроса, но это может повлиять на план оптимизации, в зависимости от реализации СУБД. Кроме того, OUTER JOIN дает другой результат, если вы включаете условия в объединение по сравнению с предложением WHERE.

1 голос
/ 02 февраля 2017

Существует разница в результате, которую я не вижу в других ответах. Если вы сделаете это:

 JOIN ... ON t1.common = t2.common

тогда результирующий набор будет иметь два столбца с именами common, в частности t1.common и t2.common, и попытка ссылки на неквалифицированное имя common приведет к отклонению запроса как неоднозначного (даже если оба столбца обязательно содержат одинаковое значение).

Если, с другой стороны, вы делаете это:

 JOIN ... USING (common)

тогда в наборе результатов будет только один столбец с именем common, и это будет неквалифицированное имя - ни t1.common, ни t2.common не будет присутствовать.

1 голос
/ 16 декабря 2008

Если есть только одно соединение, то нет никакой разницы.

Недостатком условия использования является то, что обе таблицы должны иметь одинаковое имя столбца.

1 голос
/ 16 декабря 2008

Я считаю, что вы правы - USING (xx) - это сокращение для объединения двух столбцов с одинаковыми именами.

Что касается второго вопроса, оба запроса могут быть одинаковыми или могут отличаться в зависимости от реализации планировщика запросов, специфичной для базы данных. Чтобы выяснить для себя (по крайней мере, в postgres), выполните EXPLAIN SELECT ..., чтобы увидеть, как будут выполняться планы запросов.

1 голос
/ 16 декабря 2008

Ваша интерпретация кажется правильной. Эта статья может помочь.

Что касается второго вопроса, я не понимаю, почему результат вашего третьего примера должен отличаться от результата первых двух. Любое условие в предложении «ON» имеет такое же значение, как если бы оно было в предложении «WHERE».

0 голосов
/ 20 апреля 2012

Вы получили ответы здесь, мне не нужно добавлять к этому. Однажды я сделал тест производительности на этом, и ИСПОЛЬЗОВАНИЕ последовательно и всегда работал быстрее, чем ВКЛ. Да, я говорю от 10 до 20 мс :) MySQL, я говорю о

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