Старый синтаксис с простым перечислением таблиц и использованием WHERE
предложения для указания критериев объединения в большинстве современных баз данных устарел.
Это не просто для наглядности, старый синтаксис может быть неоднозначным, когда вы используете как INNER, так и OUTER соединения в одном запросе.
Позвольте привести пример.
Предположим, у вас есть 3 таблицы в вашей системе:
Company
Department
Employee
Каждая таблица содержит множество строк, связанных между собой. У вас есть несколько компаний, и в каждой компании может быть несколько отделов, а в каждом отделе может быть несколько сотрудников.
Итак, теперь вы хотите сделать следующее:
Перечислите все компании, и включите все их отделы и всех их сотрудников. Обратите внимание, что в некоторых компаниях пока нет отделов, но обязательно включите их. Убедитесь, что вы получаете только те отделы, в которых есть сотрудники, но всегда указывайте все компании.
Итак, вы делаете это:
SELECT * -- for simplicity
FROM Company, Department, Employee
WHERE Company.ID *= Department.CompanyID
AND Department.ID = Employee.DepartmentID
Обратите внимание, что у последнего есть внутреннее соединение, чтобы выполнить критерии, которые вы хотите, чтобы отделы только с людьми.
Итак, что происходит сейчас. Проблема в том, что это зависит от механизма базы данных, оптимизатора запросов, индексов и статистики таблиц. Позволь мне объяснить.
Если оптимизатор запросов определит, что способ сделать это - сначала взять компанию, затем найти отделы, а затем выполнить внутреннее объединение с сотрудниками, вы не получите компаний, у которых нет отделов.
Причина этого заключается в том, что WHERE
предложение определяет, какие строки заканчиваются в конечном результате, а не отдельные части строк.
И в этом случае из-за левого соединения столбец Department.ID будет иметь значение NULL, и, таким образом, когда дело доходит до INNER JOIN для Employee, нет способа выполнить это ограничение для строки Employee, и поэтому он не будет появляются.
С другой стороны, если оптимизатор запросов решит сначала выполнить объединение сотрудников и сотрудников, а затем выполнить левое объединение с компаниями, вы их увидите.
Так что старый синтаксис неоднозначен. Нет никакого способа указать, что вы хотите, не имея дело с подсказками запросов, а некоторые базы данных вообще не имеют никакой возможности.
Введите новый синтаксис, с этим вы можете выбрать.
Например, если вы хотите, чтобы все компании, как указано в описании проблемы, вы написали бы следующее:
SELECT *
FROM Company
LEFT JOIN (
Department INNER JOIN Employee ON Department.ID = Employee.DepartmentID
) ON Company.ID = Department.CompanyID
Здесь вы указываете, что хотите, чтобы объединение сотрудника отдела выполнялось как одно объединение, а затем оставляете объединение результатов с компаниями.
Кроме того, допустим, вам нужны только те отделы, в названии которых есть буква X. Опять же, при объединении в старом стиле вы рискуете потерять и компанию, если у нее нет отделов с X в названии, но с новым синтаксисом вы можете сделать это:
SELECT *
FROM Company
LEFT JOIN (
Department INNER JOIN Employee ON Department.ID = Employee.DepartmentID
) ON Company.ID = Department.CompanyID AND Department.Name LIKE '%X%'
Это дополнительное предложение используется для объединения, но не является фильтром для всей строки. Таким образом, строка может отображаться с информацией о компании, но может содержать значения NULL во всех столбцах отдела и сотрудника для этой строки, поскольку для этой компании не существует отдела с X в названии. Это сложно со старым синтаксисом.
Вот почему, среди других поставщиков, Microsoft устарела старый синтаксис внешнего соединения, но не старый синтаксис внутреннего соединения, начиная с SQL Server 2005 и выше. Единственный способ общения с базой данных, работающей на Microsoft SQL Server 2005 или 2008, с использованием синтаксиса внешнего соединения старого стиля, - это установить эту базу данных в режиме совместимости 8.0 (он же SQL Server 2000).
Кроме того, по-старому, бросая кучу таблиц в оптимизатор запросов с кучей предложений WHERE, было похоже на высказывание «вот, пожалуйста, делай как можно лучше». С новым синтаксисом оптимизатору запросов меньше работы, чтобы выяснить, какие части идут вместе.
Так что у вас есть это.
LEFT и INNER JOIN - это волна будущего.