Причини появи OUTER JOIN
До речі, пам'ятаєш, ми об'єднували наші таблиці і в нас зникли завдання з прибирання офісу, оскільки самої прибиральниці ще не було?
Якщо виконати такий запит:
SELECT * FROM task
То ми отримаємо такий результат:
id | emploee_id | name | deadline |
---|---|---|---|
1 | 1 | Виправити багу на фронтенді | 2022-06-01 |
2 | 2 | Виправити багу на бекенді | 2022-06-15 |
3 | 5 | Купити каву | 2022-07-01 |
4 | 5 | Купити каву | 2022-08-01 |
5 | 5 | Купить каву | 2022-09-01 |
6 | (NULL) | Прибрати офіс | (NULL) |
7 | 4 | Насолоджуватися життям | (NULL) |
8 | 6 | Насолоджуватися життям | (NULL) |
Завдання "Прибрати офіс" зникає, якщо ми спробуємо об'єднати таблицю task із таблицею employee по employee_id.
Щоб вирішити цю проблему, оператор JOIN додали різні модифікатори, які дозволяють зберегти такі втрачені рядки без пари в іншій таблиці.
Нагадаю класичний вигляд оператора JOIN:
таблиця 1 JOIN таблиця 2 ON
умова
Ми можемо сказати SQL-серверу, щоб усі дані з лівої таблиці (таблиця1) обов'язково були присутні у об'єднаній таблиці. Навіть якщо для них немає пари у правій таблиці. Для цього лише потрібно написати:
таблиця 1 LEFT JOIN таблиця 2 ON умова
Якщо ж ти хочеш, щоб у об'єднаній таблиці обов'язково були всі рядки з правої таблиці , то потрібно написати:
таблиця 1 RIGHT JOIN таблиця 2 ON
умова
Давай напишемо запит, який поєднає всі завдання та співробітників, щоб при цьому завдання без виконавця не губабося. Для цього потрібно написати запит:
SELECT * FROM employee e RIGHT JOIN task t ON e.id = t.emploee_id
І результат такого запиту:
id | name | occupation | salary | age | join_date | id | emploee_id | name |
---|---|---|---|---|---|---|---|---|
1 | Іванов Іван | Програміст | 100000 | 25 | 2012-06-30 | 1 | 1 | Виправити багу на фронтенді |
2 | Петроов Петроо | Програміст | 80000 | 23 | 2013-08-12 | 2 | 2 | Виправити багу на бекенді |
4 | Рабінович Мойша | Директор | 200000 | 35 | 2015-05-12 | 7 | 4 | Насолоджуватися життям |
5 | Кирієнко Анастасія | Офіс менеджер | 40000 | 25 | 2015-10-10 | 3 | 5 | Купити каву |
5 | Кирієнко Анастасія | Офіс менеджер | 40000 | 25 | 2015-10-10 | 4 | 5 | Купити каву |
5 | Кирієнко Анастасія | Офіс менеджер | 40000 | 25 | 2015-10-10 | 5 | 5 | Купити каву |
6 | Васько | Кіт | 1000 | 3 | 2018-11-11 | 8 | 6 | Насолоджуватися життям |
(NULL) | (NULL) | (NULL) | (NULL) | (NULL) | (NULL) | 6 | (NULL) | Прибрати офіс |
До нашої таблиці додався ще один рядок, і що цікаво в ній дуже багато значень NULL. Усі дані, які бралися з таблиці employee, відображаються у вигляді NULL, тому що для завдання “Прибрати офіс” не знайшлося виконавця з таблиці employee.
Типи JOIN-ів
Усього існує 4 типи JOIN-ів. Вони представлені в таблиці нижче:
Короткий запис | Довгий запис | Пояснення | |
---|---|---|---|
1 | JOIN | INNER JOIN | Тільки записи, які є в таблицях А та Б |
2 | LEFT JOIN | LEFT OUTER JOIN | Усі рядки без пари з таблиці А мають бути |
3 | RIGHT JOIN | RIGHT OUTER JOIN | Усі рядки без пари з таблиці Б мають бути |
4 | OUTER JOIN | FULL OUTER JOIN | Усі рядки баз пар з таблиць А та Б повинні бути |
Для простоти, якщо ми представимо таблиці у вигляді множин, JOIN можна буде відображати у вигляді картинки:

Під перетином множин мається на увазі, що для однієї таблиці є відповідний запис з іншої таблиці, яку вона посилається.
Питання співбесіди
Іноді програмістів-новачків на співбесіді валять дуже простим питанням. З урахуванням наших таблиць його можна сформулювати так:
“Напишіть запит, який відображатиме список усіх працівників, для яких немає завдань ”. Спочатку спробуємо трохи перефразувати це питання: “Напишіть запит, який відобразить список усіх співробітників з таблиці employee, для яких немає завдань у таблиці task ”. Нам потрібно отримати ось це безліч:
Можна вирішити це завдання багатьма способами, але я почну з найпростіших: По-перше, ти можеш об'єднати наші таблиці за допомогою LEFT JOIN, а потім за допомогою WHERE виключити всі рядки, для яких дані, що були відсутні, були доповнені NULL-ами.
SELECT * FROM employee e LEFT JOIN task t ON e.id = t.emploee_id
WHERE t.id IS NULL
І результат такого запиту:
id | name | occupation | salary | age | join_date | id | emploee_id | name |
---|---|---|---|---|---|---|---|---|
3 | Іванов Сергій | Тестувальник | 40000 | 30 | 2014-01-01 | (NULL) | (NULL) | (NULL) |
Єдиний мінус такого рішення, що в таблиці рядка містять NULL, а нам за умовою потрібно відобразити список співробітників.
Для цього потрібно або перерахувати в SELECT необхідні колонки таблиці employee, або якщо потрібно відобразити їх усі, можна написати таку конструкцію:
SELECT e.* FROM employee e, task t
Повний запит буде виглядати так:
SELECT e.*
FROM employee e RIGHT JOIN task t ON e.id = t.emploee_id
WHERE t.id IS NULL
результат такого запиту:
id | name | occupation | salary | age | join_date |
---|---|---|---|---|---|
3 | Іванов Сергій | Тестувальник | 40000 | 30 | 2014-01-01 |
Інші способи залишаються вам для домашнього завдання. Не хочу позбавляти вас задоволення знайти їх самостійно.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ