Нужно выбрать пользователей, у которых число заказов выше среднего по всем пользователям. Какой запрос корректно считает «среднее по пользователям», а не «среднее по заказам»?

ASELECT o.user_id FROM orders o GROUP BY o.user_id HAVING COUNT(*) > (SELECT AVG(COUNT(*)) FROM orders GROUP BY user_id)
BSELECT o.user_id FROM orders o GROUP BY o.user_id HAVING COUNT(*) > (SELECT AVG(amount) AS avg_amt FROM orders)
CWITH cnt AS (SELECT user_id, COUNT(*) AS o FROM orders GROUP BY user_id) SELECT user_id FROM cnt WHERE o > (SELECT AVG(o) FROM cnt)
DSELECT u.user_id FROM users u WHERE u.user_id IN (SELECT AVG(orders_cnt) FROM cnt GROUP BY user_id)
Правильный ответ. Нужно сначала агрегировать заказы до уровня пользователя, а затем считать среднее уже по этому уровню.

Разбор

Среднее по пользователям означает: для каждого пользователя считаем COUNT(*), получаем таблицу «пользователь → число заказов», и только потом берём AVG по этим значениям. Если пытаться посчитать среднее напрямую по таблице orders, легко перепутать уровень данных и получить другую метрику (например, среднее по строкам заказов). CTE помогает явно зафиксировать нужную гранулярность.

Можно заниматься бесплатно

Готовим вопросы…

Три вопроса по теме этой страницы, с объяснениями.

Продолжить в браузере

Ещё вопросы по теме «Подзапросы и CTE»