Разница между INNER JOIN и WHERE

9 апреля, 2020 18:14
Admin
9 апреля, 2020 22:57

Нотация для соединения нескольких таблиц была введена в версии 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]

Источники

  1. «Изучаем SQL». Алан Бьюли