Нотация для соединения нескольких таблиц была введена в версии SQL92 стандарта ANSI SQL. На данный момент во всех основных СУБД (MySQL, Oracle Database, Microsoft SQL Server и другие) принят синтаксис соединения SQL92. Но поскольку многие серверы существовали еще до выхода спецификации SQL92, все они включают и старый синтаксис соединения с использованием ключевого слова WHERE.
Предположим, что у нас существуют 2 таблицы: users (пользователи) и users_group (группы пользователей), которые связаны между собой внешним ключом users_group_id:
CREATE TABLE users (
id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
login VARCHAR(60) UNIQUE,
email VARCHAR(60) UNIQUE,
group_id INT UNSIGNED NOT NULL,
name VARCHAR(150)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE users_group (
id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(255)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE users
ADD CONSTRAINT users_group_id FOREIGN KEY (group_id) REFERENCES users_group (id);
INSERT INTO users_group (id, name) VALUES
(1, 'administrators'),
(2, 'other'),
(3, 'manager');
INSERT INTO users (id, login, email, group_id, name) VALUES
(1, 'admin', 'admin@mail.ru', 1, 'Lex'),
(2, 'ann', 'ann@yandex.ru', 2, 'Ann'),
(3, 'bob', 'bob@mail.ru', 2, 'Bob');
Таким образом, следующий запрос можно написать двумя разными способами, используя INNER JOIN:
SELECT u.login, u.email, g.name
FROM users u INNER JOIN users_group g ON u.group_id = g.id;
Или с помощью ключевого слова WHERE:
SELECT u.login, u.email, g.name
FROM users u, users_group g WHERE u.group_id = g.id;
В этом старом методе описания соединений отсутствует подблок on. Таблицы перечисляются через запятую в блоке from, а условия соединения включены в блок where. Несмотря на это, данные два запроса вернут одинаковый результат.
Преимущества ANSI-синтаксиса соединения
Несмотря на то, что можно игнорировать синтаксис SQL92 в пользу старого синтаксиса соединений, у синтаксиса ANSI существуют следующие преимущества:
- Условия соединения и фильтрации разнесены в два разных блока (подблок on и блок where соответственно), что упрощает понимание запроса.
- Условия соединения для каждой пары таблиц содержатся в собственном блоке on, что уменьшает вероятность ошибочного исключения части соединения.
- Запросы, использующие синтаксис соединения SQL92, портируются на разные серверы БД, тогда как старый синтаксис немного отличается для каждого сервера.
Преимущества синтаксиса SQL92 заметнее в сложных запросах. [1]
Источники
- "Изучаем SQL". Алан Бьюли