Представим, что нам нужно определить, какие курсы читались и в 2022 и в 2023 году.
Другими словами, нам нужно найти пересечение двух множеств. В языке SQL это можно сделать с помощью оператора INTERSECT
.
Оператор INTERSECT
Чтобы найти пересечение двух подзапросов, нужно между ними написать оператор INTERSECT
:
SELECT coursename FROM course_members_2022
INTERSECT
SELECT coursename FROM course_members_2023;
Такой запрос вернет нам четыре строки - те курсы, которые читались в обоих годах.
coursename |
---|
Python |
SQL |
Javascript |
PHP |
View on DB Fiddle
Правила использования
Для INTERSECT
действуют те же два правила, что и для UNION
.
В обоих подзапросах должно быть одинаковое количество столбцов, а сами столбцы должны иметь одинаковые типы данных.
Два следующих запроса не выполнятся, потому что в первом разное количество столбцов в подзапросах, а во втором - столбцы разного типа
-- В первом подзапросе два столбца, а во втором один
SELECT
coursename,
username
FROM course_members_2022
INTERSECT
SELECT coursename FROM course_members_2023;
-- Столбцы двух подзапросов имеют разные типы данных - в первом текст, а во втором - дата.
SELECT username FROM course_members_2022
INTERSECT
SELECT created_at FROM course_members_2023;
Для INTERSECT
, как и для UNION
, СУБД будет следить только за тем, чтобы типы данных столбцов были одинаковые. Логический смысл СУБД не проверяет.
Если мы в первом подзапросе укажем столбец username
, а во втором - coursename
, то запрос выполнится, но вернет нам пустое множество, потому что среди названий курсов и
имен пользователей нет пересечений - они все разные.
-- Этот запрос выполнится, но строк не вернет, потому что среди username и coursename нет совпадающих значений
SELECT username FROM course_members_2022
INTERSECT
SELECT coursename FROM course_members_2023;
View on DB Fiddle
INTERSECT ALL
По умолчанию, INTERSECT
, как и UNION
не выводит дублирующиеся строки.
В первом запросе этого урока результат содержал 4 строки - уникальные названия курсов, которые читались в 2022 и в 2023 году.
-- Запрос вернет 4 строки
SELECT coursename FROM course_members_2022
INTERSECT
SELECT coursename FROM course_members_2023;
Но бывает полезно узнать не только какие записи совпадают, но и сколько их.
Если использовать оператор INTERSECT ALL
, то запрос вернет все записи, даже дублирующиеся.
-- Запрос вернет 9 строк, но курсы будут повторяться
SELECT coursename FROM course_members_2022
INTERSECT ALL
SELECT coursename FROM course_members_2023;
Результат запроса:
coursename |
---|
Python |
Python |
SQL |
SQL |
SQL |
Javascript |
Javascript |
Javascript |
PHP |
View on DB Fiddle
Это означает, что в каждом году есть как минимум 2 пользователя, записавшихся на Python, как минимум 3 пользователя, записавшихся на SQL и так далее.
Еще лучше понять этот результат INTERSECT ALL
можно, если посмотреть, сколько человек записано на курс PHP в каждом году:
SELECT coursename FROM course_members_2022
WHERE coursename = 'PHP';
SELECT coursename FROM course_members_2023
WHERE coursename = 'PHP';
Запрос вернет две таблицы.
Для 2022 года:
coursename |
---|
PHP |
PHP |
PHP |
Для 2023 года:
coursename |
---|
PHP |
View on DB Fiddle
Мы видим, что у этих таблиц общая только одна строка, поэтому последний запрос с оператором INTERSECT ALL
вывел только одну строку для курса PHP
Выводы
В этом уроке мы узнали, как можно находить пересечение двух запросов с помощью оператора INTERSECT
.
Другими словами, INTERSECT
ищет одинаковые строки двух запросов.
Для его использования необходимо соблюдение двух правил: объединяемые запросы должны иметь одинаковое количество столбцов, а сами столбцы должны иметь одинаковые типы данных.
INTERSECT
по умолчанию удаляет дублирующиеся строки. Если необходимо вывести все строки, то нужно использовать INTERSECT ALL
.
Дополнительные материалы
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.