Какая разница между "использованием" и "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
.