Столкнулись ли вы с SQL запросами с JOIN и GROUP BY
Что проверяют
Вопрос звучит как «был ли опыт», но проверяют другое: пишете ли вы SQL сами или всё делаете кодом на Go. Типичный провал бэкендера в том, что он тянет список сущностей, а потом в цикле делает по запросу на каждую. Смотрят, понимаете ли вы, что соединение и агрегация это работа базы, и знаете ли, что происходит со строками при JOIN и как ведут себя агрегаты над пустыми значениями.
Как отвечать
Расскажите про конкретную задачу и покажите запрос. Хорошая опора это отчёт вида «сколько заказов у пользователя», где видно и соединение, и группировку:
SELECT u.id, u.name, count(o.id) AS orders, coalesce(sum(o.amount), 0) AS total
FROM users u
LEFT JOIN orders o ON o.user_id = u.id AND o.status = 'paid'
GROUP BY u.id, u.name;Проговорите ключевое: WHERE фильтрует строки до группировки, порог по агрегату ставится в HAVING. Условие по правой таблице во внешнем соединении идёт в ON, а не в WHERE, иначе соединение молча превращается во внутреннее. В Postgres в GROUP BY должны попасть все неагрегированные колонки, либо группировка идёт по первичному ключу, и тогда остальные поля той же таблицы разрешены.
Со стороны Go добавьте, что колонки из внешнего соединения приезжают пустыми, поэтому в структуре нужны sql.NullString или указатели, что запрос идёт с QueryContext и таймаутом и что rows.Err() проверяется после цикла.
Где спотыкаются
count(*) после внешнего соединения даёт единицу там, где связанных строк нет: считается сама строка пользователя с пустым правым краем. Нужен count(o.id), а для условной агрегации в Postgres удобнее count(*) FILTER (WHERE ...).
Соединяют две таблицы «один ко многим» сразу и суммируют. Строки перемножаются, суммы раздуваются, и DISTINCT это не чинит. Агрегировать надо в отдельных подзапросах и соединять уже готовые итоги.
Забывают rows.Close() и rows.Err(). Соединение не возвращается в пул, пул упирается в SetMaxOpenConns, и сервис встаёт целиком, хотя база при этом свободна.