У 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 для Співробітника, немає можливості виконати це обмеження для ряду Співробітник, і тому воно не буде з'являються.
З іншого боку, якщо оптимізатор запитів вирішить спочатку приєднатись до співробітника відділу, а потім приєднатись до компаній зліва, ви побачите їх.
Тож старий синтаксис неоднозначний. Немає можливості вказувати, що ви хочете, не маючи справу з підказками запитів, а деякі бази даних взагалі не мають можливості.
Введіть новий синтаксис, за допомогою якого ви можете вибрати.
Наприклад, якщо ви хочете, щоб усі компанії, як зазначено в описі проблеми, писали:
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, був схожий на те, щоб сказати "ось ти, роби найкраще". З новим синтаксисом оптимізатору запитів менше роботи, щоб зрозуміти, які частини поєднуються.
Так ось у вас це є.
ЛІВ І ВНУТРІШНЯ ПРИЄДНАЙТЕСЬ - це хвиля майбутнього.