Старый синтаксис с простым перечислением таблиц и использованием предложения 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, был похож на выражение «вот, пожалуйста, делай как можно лучше». С новым синтаксисом оптимизатору запросов меньше работы, чтобы выяснить, какие части идут вместе.
Итак, вот оно.
ВЛЕВО и ВНУТРЕННЕЕ СОЕДИНЕНИЕ - волна будущего.