Какая разница между "использованием" и "on" в таблице объединяется в MysQL?

Это

... 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 взаимодействуют с соединением vs, если его в предложении where?

Ответ 1

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

  • большинство моих соединений не подходят для него (не то же самое имя поля, которое соответствует, и/или несколько совпадений в соединении), и
  • не сразу видно, что он переводит в случае с более чем двумя таблицами

т.е. предполагая 3 таблицы с столбцами 'id' и 'id_2', делает

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

стать

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 с одним полем идентификатора, одна строка содержит значение 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

не содержит строк, так как WHERE необходимо сопоставить, тогда как

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, что является необязательным из-за внешнего.

Ответ 2

Предложение 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.

Ответ 3

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

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

Ответ 4

Я считаю, что вы правы. ИСПОЛЬЗОВАНИЕ (xx) - это короткая рука для объединения двух столбцов с одинаковыми именами.

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

Ответ 5

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

Даунсайд к предложению using обе таблицы должны иметь одинаковое имя столбца.

Ответ 6

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

Ответ 7

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

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

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

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

 JOIN ... USING (common)

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