Задачи на SELECT и WHERE
Выборка и фильтры·junior

Должники: невозвращённые диски

Задача

В прокате завал: часть дисков разошлась по рукам и не вернулась. Менеджер просит список открытых аренд, чтобы обзвонить должников: «Дай все прокаты, которые ещё не закрыты возвратом».

Верни 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)

Прорешай такие задачи сам

Читать разбор полезно, а настоящая прокачка — самому писать запросы и получать обратную связь. В симуляторе живая база и проверка запросов, лёгкий режим — бесплатно.

Прорешать в бесплатной песочнице

Смежные задачи

Вопросы по теме