Добавить в корзинуПозвонить
Найти в Дзене

Виды соединений таблиц (2 часть): внешние/внутренние, using и natural join

Продолжим наше обсуждение соединения таблиц в SQL. Можно разделить их на 2 основных вида: Слова [inner] и [outer] опциональны, и их обычно не пишут. В мануалах [] cкобки зачастую означают, что оператор не обязателен. Внутренние соединения в 99% случаев пишут через ON, например: Однако в некоторых базах данных (например Оракле) есть возможность соединиться использую ключевое слово USING. Оно подразумевает "equijoin" (эквивалентное соединение), то есть внутреннее соединение через равенство полей. Внутрь скобок оператора USING через запятую нужно поместить столбцы по которым хотим соединиться. Использование USING возможно, если наименование и тип данных колонок совпадает, например: Однако, если бы в таблице customers ключевое поле называлось бы не customer_id, а просто id, как это часто и бывает, то соединиться уже бы не получилось. Так же обратите внимание, что в случае с ON и SELECT *, мы получим все колонки как из первой таблицы, так и второй. Однако, используя USING, колонки, по ко
Внутренние и внешние соединения
Внутренние и внешние соединения

Продолжим наше обсуждение соединения таблиц в SQL. Можно разделить их на 2 основных вида:

  • внутренние (inner join), строки по выбранному соединению выводятся, только если присутствуют в обоих таблицах;
  • внешние (outer join), выводятся все строки из основной таблицы, из дополнительной выводятся строки, по которым произошло соединение и пустые значения (null), если соединиться не получилось.

Слова [inner] и [outer] опциональны, и их обычно не пишут. В мануалах [] cкобки зачастую означают, что оператор не обязателен.

Внутренние соединения в 99% случаев пишут через ON, например:

Самый обычный join
Самый обычный join

Однако в некоторых базах данных (например Оракле) есть возможность соединиться использую ключевое слово USING. Оно подразумевает "equijoin" (эквивалентное соединение), то есть внутреннее соединение через равенство полей. Внутрь скобок оператора USING через запятую нужно поместить столбцы по которым хотим соединиться. Использование USING возможно, если наименование и тип данных колонок совпадает, например:

Join с использование using
Join с использование using

Однако, если бы в таблице customers ключевое поле называлось бы не customer_id, а просто id, как это часто и бывает, то соединиться уже бы не получилось. Так же обратите внимание, что в случае с ON и SELECT *, мы получим все колонки как из первой таблицы, так и второй. Однако, используя USING, колонки, по которым соединяемся, будут выведены только один раз.

Можно пойти еще дальше, и вообще не прописывать колонок для соединения. Для этого мы можем использовать natural join. Соединение произойдет автоматически по колонкам с одинаковым названием, если у них совпадает тип данных (если нет, выдаст ошибку). Стоит отметить, что натуральное соединение - внутреннее. Синтаксис следующий: natural join tableX. Пример:

Natural join двух таблиц
Natural join двух таблиц

Соединение natural join редко используется, т.к. оно не надежное. Представьте, что у вас есть некая процедура которая ежедневно делает расчет продаж по клиентам, и таблицы продуктов и клиентов соединяется по 2 полям: id_client и id_product. Теперь представьте, что кто-то поменяет название столбца id_product, на id в родительской таблице. В таком случае, процедура все равно продолжит работать и не выдаст ошибку, т.к. сможет соединиться по оставшемуся общему столбцу id_client, но при этом начнет выдавать лишние строки. Если бы соединение было через ON, то при переименовании столбца, процедура сразу выдала бы ошибку и мы заметили ее гораздо раньше, чем через пару месяцев, когда кто-то в бизнесе увидит, что данные в таком-то отчете поплыли.

Для чего ж его тогда вообще реализовали? Я думаю, это больше как попытка приблизить стандарт SQL к оригинальной реляционной теории, где есть оператор натурального соединения - ⨝.

В MS SQL Server нельзя использовать using, так же как и natural join. В Oracle, PostgreSQL и MySQL - можно.

В следующей статье рассмотрим partitioned outer join.

Предыдущая статья: Виды соединений таблиц: введение (1 часть)