Напиши SQL запрос для вывода суммы продаж по каждому пользователю, учитывая, что у пользователя может не быть продаж
Что проверяют
Место то же, что и в чистом SQL: обычное соединение теряет пользователей без продаж, а sum по пустой группе даёт NULL. Но питониста дополнительно проверяют на границу приложения и базы: считает агрегат СУБД или цикл в коде, и умеете ли вы выразить внешнее соединение средствами ORM.
Как отвечать
Начните с запроса, он короткий и снимает половину вопросов:
SELECT u.id, u.name, COALESCE(sum(s.amount), 0) AS total
FROM users u
LEFT JOIN sales s ON s.user_id = u.id
GROUP BY u.id, u.name;Затем покажите тот же смысл в ORM, скорее всего об этом и спросят следующим вопросом:
stmt = (
select(User.id, User.name, func.coalesce(func.sum(Sale.amount), 0))
.outerjoin(Sale, Sale.user_id == User.id)
.group_by(User.id, User.name)
)В Django тот же результат даёт annotate с Coalesce(Sum("sale__amount"), 0). Подчеркните, что это один запрос, а не выборка пользователей с последующим проходом по связям, и предупредите про известную ловушку: два агрегата по разным связям в одном annotate перемножают строки и завышают обе суммы.
Где спотыкаются
Отвечают кодом на Python: выбирают всех пользователей, в цикле запрашивают продажи каждого и складывают. Получается классическая проблема лишних запросов, а на больших таблицах ещё и память. Агрегация это работа базы, приложение забирает готовое число.
Забывают COALESCE и ловят None там, где ждали число. Форматирование суммы, сравнение с порогом, сложение в итоговой строке отчёта, всё это падает или тихо пропускает пользователя, а тест на данных, где продажи есть у всех, ничего не замечает.
Складывают деньги во float. Копейки уплывают на сотых долях, итог перестаёт сходиться с бухгалтерией, и объяснять это потом дороже, чем сразу взять Decimal в коде и тип numeric в базе.