Skip to main content

Як працює right join?

SQL RIGHT JOIN повертає всі рядки з правої таблиці і тільки ті рядки з лівої, які мають збіг. Де збігу немає, у лівих колонках буде NULL.

Теорія

TL;DR

  • Аналогія: кожне замовлення зі списку потрапляє у звіт, дані клієнта підставляються лише там, де є збіг.
  • Головна різниця: RIGHT JOIN зберігає всі рядки правої таблиці. INNER JOIN залишає тільки збіги. LEFT JOIN зберігає всі рядки лівої таблиці.
  • Правило вибору: права таблиця = основа даних (всі відправлення мають бути у звіті) → RIGHT JOIN. Інакше → LEFT JOIN або INNER JOIN.
  • A RIGHT JOIN B рівнозначне B LEFT JOIN A.

Швидкий приклад

sql
CREATE TABLE clients (id INT, name VARCHAR(50)); INSERT INTO clients VALUES (1, 'Alice'), (2, 'Bob'); CREATE TABLE orders (order_id INT, client_id INT, item VARCHAR(50)); INSERT INTO orders VALUES (101, 1, 'Laptop'), (102, NULL, 'Mouse'), (103, 3, 'Keyboard'); -- Всі замовлення у результаті; клієнти підставляються де є збіг SELECT c.name, o.item FROM clients c RIGHT JOIN orders o ON c.id = o.client_id;

Результат:

name | item Alice | Laptop NULL | Mouse NULL | Keyboard

Всі 3 замовлення у результаті. Замовлення 102 і 103 не мають відповідного клієнта, тому name = NULL.

Ключова різниця

RIGHT JOIN - це дзеркало LEFT JOIN. LEFT залишає всі рядки лівої таблиці і підставляє NULL справа, де збігів немає. RIGHT робить навпаки: кожен рядок правої таблиці зберігається, ліві колонки стають NULL без збігу. На практиці більшість команд переписують RIGHT JOIN як LEFT JOIN зі зміненим порядком таблиць - так основна таблиця стоїть першою і код читається природніше. Оптимізатор запитів виконує обидва варіанти однаково.

Коли використовувати

  • Всі рядки правої таблиці мають бути у результаті → RIGHT JOIN (всі відправлення, всі події у логах).
  • Всі рядки лівої таблиці мають бути у результаті → LEFT JOIN.
  • Тільки збіги важливі → INNER JOIN.
  • Все з обох таблиць → FULL OUTER JOIN.

Таблиця порівняння

Тип з'єднанняРядки лівої таблиціРядки правої таблиціNULL уТиповий сценарій
INNER JOINТільки збігиТільки збігиНемаєКлієнти з замовленнями
LEFT JOINВсіТільки збігиПраві колонкиВсі клієнти + їхні замовлення
RIGHT JOINТільки збігиВсіЛіві колонкиВсі замовлення + дані клієнтів
FULL OUTER JOINВсіВсіОбидві сторониПовний аудит, злиття даних

Типові помилки

Помилка: фільтрація NULL через WHERE після RIGHT JOIN

sql
-- Неправильно: перетворює RIGHT JOIN на INNER JOIN SELECT * FROM clients c RIGHT JOIN orders o ON c.id = o.client_id WHERE c.name IS NOT NULL;

WHERE виконується після з'єднання. Умова WHERE c.name IS NOT NULL видаляє всі рядки правої таблиці без збігу. Результат стає таким самим як у INNER JOIN. Якщо потрібно фільтрувати ліву таблицю зі збереженням усіх правих рядків, перемісти умову в ON:

sql
-- Правильно: умова в ON, рядки правої таблиці зберігаються SELECT * FROM clients c RIGHT JOIN orders o ON c.id = o.client_id AND c.name IS NOT NULL;

Помилка: очікування що NULL у ключі з'єднання зникне

Якщо order.client_id є NULL, рядок все одно потрапляє у результат. NULL не дорівнює NULL, збігу немає, і c.name буде NULL. Рядок не видаляється.

Помилка: змішування RIGHT JOIN і LEFT JOIN в одному запиті

FROM clients RIGHT JOIN orders - це те саме що FROM orders LEFT JOIN clients. Більшість команд використовують LEFT JOIN, бо головна таблиця стоїть першою. Коли в одному запиті є і LEFT, і RIGHT JOIN, логіку стає важко відстежувати.

Де зустрічається

  • E-commerce: всі відправлення з опціональними даними клієнтів (shipments RIGHT JOIN customers).
  • Логування: всі події з опціональними даними сесії, щоб жоден запис не загубився.
  • HR-системи: всі записи співробітників з опціональними відділами.
  • Аналітика: всі покази реклами з опціональними даними кліків.

Питання на співбесіді

Q: Що буде, якщо ключ з'єднання у правій таблиці NULL?
A: Рядок правої таблиці все одно потрапляє у результат. NULL не дорівнює NULL, збігу немає, ліві колонки = NULL.

Q: Як переписати RIGHT JOIN як LEFT JOIN?
A: Поміняй таблиці місцями і зміни тип з'єднання. FROM A RIGHT JOIN B ON A.id = B.id стає FROM B LEFT JOIN A ON B.id = A.id.

Q: Чому фільтр WHERE на ліву таблицю ламає поведінку RIGHT JOIN?
A: WHERE виконується після з'єднання. WHERE left.col IS NOT NULL видаляє всі рядки правої таблиці без збігу, результат як у INNER JOIN. Для фільтрації лівої таблиці використовуй умову в ON.

Q: У ланцюжку A RIGHT JOIN B RIGHT JOIN C як поширюються NULL?
A: Кожне з'єднання виконується зліва направо. Якщо A не має збігу з B, колонки A стають NULL. Це NULL бере участь у наступному з'єднанні з C. Намалюй два окремих з'єднання щоб побачити як NULL рухається по ланцюжку.

Приклади

Базовий: всі замовлення з опціональними іменами клієнтів

sql
CREATE TABLE clients (id INT, name VARCHAR(50)); INSERT INTO clients VALUES (1, 'Alice'), (2, 'Bob'); CREATE TABLE orders (order_id INT, client_id INT, item VARCHAR(50)); INSERT INTO orders VALUES (101, 1, 'Laptop'), (102, NULL, 'Mouse'), (103, 3, 'Keyboard'); SELECT c.name, o.order_id, o.item FROM clients c RIGHT JOIN orders o ON c.id = o.client_id; -- name | order_id | item -- Alice | 101 | Laptop -- NULL | 102 | Mouse <- немає client_id -- NULL | 103 | Keyboard <- client_id 3 не існує

Замовлення 102 і 103 не мають відповідного запису у clients. RIGHT JOIN зберігає їх у результаті.

Середній рівень: звіт про відправлення в e-commerce

sql
CREATE TABLE customers (cust_id INT, email VARCHAR(100)); INSERT INTO customers VALUES (1, 'alice@shop.com'), (2, 'bob@shop.com'); CREATE TABLE shipments (ship_id INT, cust_id INT, status VARCHAR(20)); INSERT INTO shipments VALUES (5001, 1, 'Delivered'), (5002, NULL, 'Pending'), (5003, 2, 'Shipped'), (5004, 3, 'Cancelled'); SELECT s.ship_id, s.status, c.email FROM customers c RIGHT JOIN shipments s ON c.cust_id = s.cust_id ORDER BY s.ship_id; -- ship_id | status | email -- 5001 | Delivered | alice@shop.com -- 5002 | Pending | NULL -- 5003 | Shipped | bob@shop.com -- 5004 | Cancelled | NULL

Всі 4 відправлення у логістичному звіті. Відправлення 5002 і 5004 не мають зареєстрованого клієнта, але бізнес все одно повинен їх відстежувати. Саме для цього і існує RIGHT JOIN.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.

Дочитали статтю?