Условие
В таблице task_1 есть ID (целое) и PROFIT_FAMILY (доход семьи). Посчитайте, насколько в среднем доход семьи у клиентов с ID = 2n (чётный) больше дохода у клиентов с ID = 2n+1 (нечётный), где n — произвольное целое.
То есть нужно: AVG(PROFIT_FAMILY | ID чётное) − AVG(PROFIT_FAMILY | ID нечётное). Округлить до 2 знаков.
Решение
Подход
Классический паттерн conditional aggregation: внутри одного SELECT с помощью CASE WHEN строим две «параллельные» подвыборки и считаем по ним агрегаты. Никаких подзапросов и JOIN не нужно.
Чётность определяется через остаток от деления: ID % 2 = 0 (Postgres/MySQL) или MOD(ID, 2) = 0.
Реализация
SELECT
ROUND(
AVG(CASE WHEN ID % 2 = 0 THEN profit_family END) -
AVG(CASE WHEN ID % 2 != 0 THEN profit_family END),
2
) AS fam_diff
FROM task_1;CASE WHEN ... THEN x END (без ELSE) подставит NULL для «другой» половины — а AVG корректно игнорирует NULL и среднее берётся только по матчующим строкам.
Альтернатива: через FILTER
SELECT
ROUND(
AVG(profit_family) FILTER (WHERE ID % 2 = 0)
- AVG(profit_family) FILTER (WHERE ID % 2 = 1),
2
) AS fam_diff
FROM task_1;Чище читается, но FILTER есть не во всех СУБД.
Альтернатива: через GROUP BY + LEAD/LAG или поворот
Можно сгруппировать по чётности и затем вычесть, но для разовой пары групп это избыточно.
Подводные камни
- Учёт
ELSE. Если случайно поставитьELSE 0,AVGначнёт считать нули у «другой половины» как валидные значения и среднее уйдёт в пол. БезELSE—NULLи они игнорируются. %в SQL Server. В MS SQL%работает, но возвращает тот же тип; в Oracle нужноMOD(ID, 2). На MySQL/Postgres%ок.- Знак. Условие задачи — «чётные больше нечётных». Разница может оказаться отрицательной — это и будет ответ, не нужно брать модуль.
NULLвID. Если вIDестьNULL,ID % 2дастNULL— такая запись не попадёт ни в одну ветку, что корректно.NULLвprofit_family.AVGих игнорирует. Если задача требует «считать как 0» — нужно явноCOALESCE(profit_family, 0).
Эталонный ответ
SELECT ROUND(
AVG(CASE WHEN id % 2 = 0 THEN profit_family END) -
AVG(CASE WHEN id % 2 != 0 THEN profit_family END),
2) AS fam_diff
FROM task_1;Положительное значение → у «чётных» клиентов в среднем доход выше; отрицательное → ниже. Если значение близко к нулю на тестовых данных, это нормально: чётность ID — обычно случайность, и эффекта быть не должно.