Должники: невозвращённые диски
Задача
В прокате завал: часть дисков разошлась по рукам и не вернулась. Менеджер просит список открытых аренд, чтобы обзвонить должников: «Дай все прокаты, которые ещё не закрыты возвратом».
Верни rental_id, дату выдачи и customer_id по всем арендам, у которых нет отметки о возврате.
Схема данных
Учебная база проката dvdrental, одна таблица:
rental(rental_id, rental_date, inventory_id, customer_id, return_date, ...)— факты выдачи дисков. Если диск вернули, вreturn_dateстоит дата; если ещё нет — тамNULL.
Решение
SELECT rental_id, to_char(rental_date, 'YYYY-MM-DD HH24:MI') AS rental_date, customer_id
FROM rental
WHERE return_date IS NULL
ORDER BY rental_date;
Разбор
Вся задача держится на одном: «диск не вернули» — это return_date IS NULL, а не return_date = NULL. И вот тут спотыкается почти каждый джун.
В SQL NULL — это не значение, а признак «данных нет». Поэтому любое сравнение с ним через обычные операторы даёт не TRUE и не FALSE, а третий результат — UNKNOWN. Запрос WHERE return_date = NULL не упадёт с ошибкой, он просто молча вернёт ноль строк: условие UNKNOWN строку в результат не пускает. Человек смотрит на пустой ответ и час ищет несуществующий баг.
Правильный инструмент — специальный оператор IS NULL (и парный IS NOT NULL). Он проверяет именно «пусто/не пусто» и возвращает честные TRUE/FALSE. Так что «ещё не вернули» = IS NULL, а «уже вернули» = IS NOT NULL.
Отдельная ловушка на собеседовании — как NULL ведёт себя в отрицаниях и в NOT IN. Про это стоит держать в голове целую картину: как NULL ведёт себя в SQL — там разобрано, почему NULL ломает и =, и агрегаты, и NOT IN-списки.
ORDER BY rental_date в конце — просто чтобы сверху оказались самые старые долги: по ним звонить в первую очередь. В SELECT дату выдачи оборачиваю в to_char(rental_date, 'YYYY-MM-DD HH24:MI') — только для читаемого вывода, фильтр и сортировка по-прежнему работают с исходной колонкой timestamp.
Ожидаемый результат
rental_id | rental_date | customer_id
--- | --- | ---
14098 | 2005-08-21 00:30 | 554
11541 | 2006-02-14 15:16 | 335
12101 | 2006-02-14 15:16 | 479
11563 | 2006-02-14 15:16 | 83
11577 | 2006-02-14 15:16 | 219
11593 | 2006-02-14 15:16 | 99
11611 | 2006-02-14 15:16 | 192
11646 | 2006-02-14 15:16 | 11
11652 | 2006-02-14 15:16 | 597
11657 | 2006-02-14 15:16 | 53
… всего строк: 183 (показаны первые 10)
Прорешай такие задачи сам
Читать разбор полезно, а настоящая прокачка — самому писать запросы и получать обратную связь. В симуляторе живая база и проверка запросов, лёгкий режим — бесплатно.
Прорешать в бесплатной песочнице