Поиск недостающего
LEFT JOIN помечает строки без пары значениями NULL, а NULL легко найти с помощью IS NULL. Вместе они отвечают на вопросы о том, чего не хватает. Какие клиенты ещё ничего не заказывали?
SELECT c.name, c.email
FROM customers AS c
LEFT JOIN orders AS o ON o.customer_id = c.id
WHERE o.id IS NULL
ORDER BY c.name;| name | |
|---|---|
| Henry Scott | henry@scott.dev |
| Max Baker | max.baker@mail.com |
Шаг за шагом: LEFT JOIN даёт каждого клиента с каждым его заказом, а каждого клиента без заказов — один раз, с NULL. Это результат из предыдущего упражнения. Затем WHERE оставляет только строки, где o.id равен NULL, а это в точности клиенты, для которых заказ не нашёлся.
Какой столбец правой таблицы проверять? Тот, который никогда не равен NULL в строке, нашедшей пару: её первичный ключ или столбец с NOT NULL. У order_items и reviews нет id, поэтому проверяйте, например, i.order_id или r.stars. Не выбирайте столбец, который и так может быть NULL, например comment отзыва: вы получите и игры, у которых отзыв есть, просто без комментария.
Типичная ошибка — WHERE o.id = NULL. Как вы знаете из урока 3, = NULL никогда не бывает истинным, поэтому запрос ничего не найдёт. Он ничего не найдёт и тогда, когда вы напишете JOIN вместо LEFT JOIN: в JOIN нет строк с NULL, потому что он отбрасывает строки без пары раньше, чем WHERE их увидит.
Для обратного вопроса — какие клиенты что-то заказывали — хватит обычного JOIN. Каждый клиент попал бы в результат столько раз, сколько у него заказов, поэтому добавьте DISTINCT: SELECT DISTINCT c.name FROM customers AS c JOIN orders AS o ON ….
Задание
- 1
Какие игры ещё никто не заказывал? Начните с запроса, который соединяет
games(псевдонимg) сorder_items(псевдонимi) так, чтобы каждая игра осталась в результате, и показываетtitleиpriceигры. - 2
Теперь добавьте условие, которое оставляет только игры, которых нет ни в одном заказе, и отсортируйте их по
title:title price Lost Temple 20 Mystery Manor 25 Robot Rebellion 40 - 3
Ниже напишите запрос, который находит игры без отзывов: их
titleи дату выхода (released), отсортированные поtitle. Две из них ещё не вышли, поэтому у них вreleasedстоит NULL. Это NULL самой игры, а не признак отсутствующего отзыва:title released Castle Siege 2021-05-20 Lost Temple 2022-04-07 Mystery Manor NULL Robot Rebellion NULL