FULL JOIN (FULL OUTER JOIN) — как он работает и чем отличается от LEFT?
Сверяю две таблицы: список сотрудников и список выданных пропусков. Хочу увидеть и тех, у кого нет пропуска, и пропуска, не привязанные ни к кому. Подсказали FULL JOIN, но я не до конца понял, как он работает и чем отличается от LEFT JOIN.
SELECT *
FROM employees e
FULL JOIN passes p ON e.id = p.employee_id;
Что именно попадёт в результат?
2 ответа
FULL JOIN (он же FULL OUTER JOIN) возвращает все строки из обеих таблиц. Там, где совпадение по ON есть — строки объединяются; там, где совпадения нет — недостающая сторона заполняется NULL.
Пример. Таблицы:
employees passes
id | name employee_id | card
1 | Аня 1 | A-01
2 | Боря 3 | C-03
Запрос:
SELECT e.name, p.card
FROM employees e
FULL JOIN passes p ON e.id = p.employee_id;
Результат:
name | card
Аня | A-01 -- совпало
Боря | NULL -- сотрудник без пропуска
NULL | C-03 -- пропуск без сотрудника (employee_id=3 нет в employees)
То есть это ровно то, что тебе нужно: видны и «безпропускные» сотрудники, и «бесхозные» пропуска.
Отличие от LEFT JOIN: LEFT JOIN берёт все строки только левой таблицы (employees) плюс совпадения справа. Строка с C-03 в LEFT не попала бы. FULL JOIN = LEFT + «хвост» правой таблицы.
Чтобы найти только несовпадения (расхождения), добавь условие:
SELECT e.name, p.card
FROM employees e
FULL JOIN passes p ON e.id = p.employee_id
WHERE e.id IS NULL OR p.employee_id IS NULL;
Важно: FULL JOIN поддерживают не все СУБД. В PostgreSQL, SQL Server, Oracle он есть, а вот в MySQL его нет — там придётся эмулировать через LEFT JOIN ... UNION ... RIGHT JOIN. Так что если запрос «не понимает» FULL JOIN — скорее всего ты на MySQL/MariaDB.