Кажется, что можно объединить две или более таблиц, мы можем использовать либо join, либо where. Какие преимущества у одного перед другим?
Кажется, что можно объединить две или более таблиц, мы можем использовать либо join, либо where. Какие преимущества у одного перед другим?
Ответы:
Любой запрос, включающий более одной таблицы, требует некоторой формы ассоциации для связывания результатов из таблицы «A» с таблицей «B». Традиционные (ANSI-89) способы сделать это:
Запишите связь между таблицами в предложении WHERE
SELECT *
FROM TABLE_A a,
TABLE_B b
WHERE a.id = b.id
Вот запрос, переписанный с использованием синтаксиса ANSI-92 JOIN:
SELECT *
FROM TABLE_A a
JOIN TABLE_B b ON b.id = a.id
Там, где это поддерживается (Oracle 9i +, PostgreSQL 7.2+, MySQL 3.23+, SQL Server 2000+), использование одного синтаксиса по сравнению с другим не дает преимущества в производительности. Оптимизатор видит их как один и тот же запрос. Но более сложные запросы могут выиграть от использования синтаксиса ANSI-92:
Существует множество причин использовать синтаксис ANSI-92 JOIN вместо ANSI-89:
Синтаксис ANSI-92 JOIN - это шаблон, а не анти-шаблон:
За исключением знакомства и / или комфорта, я не вижу никакой пользы в продолжении использования предложения ANSI-89 WHERE вместо синтаксиса ANSI-92 JOIN. Некоторые могут пожаловаться, что синтаксис ANSI-92 более подробный, но именно это делает его явным. Чем яснее, тем легче его понять и поддерживать.
Большинство людей склонны находить синтаксис JOIN немного более ясным относительно того, что к чему присоединяется. Кроме того, он является стандартом.
Лично я «вырос» на WHEREs, но чем больше я использую синтаксис JOIN, тем больше я начинаю понимать, насколько он понятнее.
Вот проблемы с использованием синтаксиса where (также известного как неявное соединение):
Во-первых, слишком легко получить случайные перекрестные соединения, потому что условия объединения не соответствуют именам таблиц. Если у вас есть 6 таблиц, соединяемых вместе, легко пропустить одну в предложении where. Вы слишком часто будете видеть это исправленным, используя ключевое слово own. Это огромный удар по производительности для базы данных. Вы не можете получить случайное перекрестное соединение, используя явный синтаксис соединения, так как это приведет к сбою проверки синтаксиса.
Правое и левое объединение проблематично (на сервере SQl вы не гарантируете получение правильных результатов) в старом синтаксисе некоторых баз данных. Кроме того, я знаю, что они устарели в SQL Server.
Если вы собираетесь использовать перекрестное соединение, это не ясно из старого синтаксиса. Это понятно с использованием действующего стандарта ANSII.
Сопровождающему намного сложнее увидеть, какие именно поля являются частью соединения или даже какие таблицы объединяются в каком порядке, используя неявный синтаксис. Это означает, что для проверки запросов может потребоваться больше времени. Я знал очень мало людей, которые, как только они нашли время, чтобы освоиться с явным синтаксисом соединения, когда-либо вернулись к старому пути.
Я также заметил, что некоторые люди, использующие эти неявные объединения, на самом деле не понимают, как работают объединения, и поэтому получают неверные результаты в своих запросах.
Честно говоря, вы бы использовали какой-нибудь другой код, который 18 лет назад заменили на лучший метод?
Явные соединения передают намерение, оставляя предложение where для фильтрации. Он чище и стандартен, и вы можете делать такие вещи, как левый внешний или правый внешний, что сложнее сделать только с помощью where.
Вы не можете использовать WHERE для объединения двух таблиц. Что вы можете сделать, так это написать:
SELECT * FROM A, B
WHERE ...
Запятая здесь эквивалентна написанию:
SELECT *
FROM A
CROSS JOIN B
WHERE ...
Вы бы это написали? Нет - потому что это совсем не то, что вы имеете в виду. Вам не нужно перекрестное соединение, вам нужно ВНУТРЕННЕЕ СОЕДИНЕНИЕ. Но когда вы пишете запятую, вы говорите CROSS JOIN, и это сбивает с толку.
На самом деле вам часто нужны и "WHERE", и "JOIN".
«JOIN» используется для извлечения данных из двух таблиц на основе значений общего столбца. Если вы хотите дополнительно отфильтровать этот результат, используйте предложение WHERE.
Например, «LEFT JOIN» извлекает ВСЕ строки из левой таблицы плюс совпадающие строки из правой таблицы. Но это не фильтрует записи по какому-либо конкретному значению или по другим столбцам, которые не являются частью JOIN. Таким образом, если вы хотите дополнительно отфильтровать этот результат, укажите дополнительные фильтры в предложении WHERE.