Напиши SQL запрос для выбора названий всех книг, которые сейчас на руках у пользователей
Что проверяют
Умеете ли вы выразить состояние через данные. «На руках» это не колонка в таблице книг, а факт: есть запись о выдаче, и в ней не проставлена дата возврата. Проверяют понимание NULL и умение выбрать нужный вид соединения.
Как отвечать
Опишите схему, которую предполагаете: книги, пользователи и выдачи со ссылками на тех и других и с датой возврата. Дальше запрос:
SELECT DISTINCT b.title
FROM books b
JOIN loans l ON l.book_id = b.id
WHERE l.returned_at IS NULL;Эквивалент через полусоединение часто читается лучше и не заставляет базу отдельно убирать дубли:
SELECT b.title
FROM books b
WHERE EXISTS (
SELECT 1 FROM loans l
WHERE l.book_id = b.id AND l.returned_at IS NULL
);Проговорите ключевое: NULL не сравнивается ни с чем через =, работает только IS NULL. Уточните, есть ли в схеме отдельный статус выдачи и считаются ли экземпляры книги отдельно от названия. В части Go упомяните, что обнуляемая дата читается в sql.NullTime или в указатель, иначе скан упадёт на первой же незакрытой выдаче.
Где спотыкаются
Пишут l.returned_at = NULL и получают пустой результат без единой ошибки. Это самая частая ошибка на этом вопросе, и она молчаливая: запрос отработал, строк ноль, причина неочевидна.
Забывают про дубли. Одна и та же книга бывает выдана несколькими экземплярами или имеет длинную историю выдач, и без DISTINCT либо EXISTS название повторится столько раз, сколько нашлось подходящих строк.
Меняют JOIN на LEFT JOIN для надёжности. Тогда в выдачу попадают книги, которых вообще никто не брал: у них вся правая часть заполнена NULL, и условие returned_at IS NULL для них истинно. Условие по правой таблице при внешнем соединении переносится в ON.