Приведи пример использования агрегатной функции
Что проверяют
Знаете ли вы SQL на уровне, достаточном для сервиса на Go, и понимаете ли, как результат агрегата приезжает в код. Вопрос простой, но по нему видно, писали ли вы запросы сами или только дёргали готовый слой доступа.
Как отвечать
Агрегатная функция сворачивает набор строк в одно значение: count, sum, avg, min, max. Без group by схлопывается вся выборка, с ним получается строка на группу:
select status, count(*) as cnt, sum(amount) as total
from orders
where created_at >= now() - interval '7 days'
group by status
having sum(amount) > 0;where отсекает строки до группировки, having фильтрует уже готовые группы.
Дальше покажите сторону Go, ради которой вопрос и задан:
var total sql.NullInt64
err := db.QueryRowContext(ctx,
`select sum(amount) from orders where user_id = $1`, id).Scan(&total)sum по пустой выборке возвращает NULL, и скан в обычный int64 упадёт на преобразовании. Либо принимаете sql.NullInt64, либо пишете coalesce(sum(amount), 0) прямо в запросе. У count такой беды нет: по пустой выборке он честно отдаёт ноль.
Закончите тем, что агрегацию выгоднее делать в базе, а не тянуть строки в сервис и складывать циклом: меньше трафика, меньше памяти под результат, и запрос может целиком покрыться индексом.
Где спотыкаются
Показывают функцию на Go, которая суммирует слайс, и называют её агрегатной. Термин пришёл из SQL, и такой ответ читается как «с базой я толком не работал».
Пишут условие по агрегату в where. На момент фильтрации строк групп ещё нет, поэтому count(*) > 5 живёт только в having, а попытка иначе просто не выполнится.
Сканируют sum или avg в обычный числовой тип. Код работает, пока у пользователя есть заказы, и падает на новом аккаунте с пустой историей. На наполненной тестовой базе это не ловится, зато прекрасно ловится в проде.