MiddleКодЧастоЕщё не отвечали
Топ-10 RU-клиентов по сумме корзины выше порога
Таблицы customer(id, email, country) и cart_item(id, customer_id, title, amount, price). Верните id и email десяти клиентов из России с наибольшей суммой корзины.
Требования:
- отфильтровать по
country = 'ru' - сумма каждого клиента —
SUM(amount * price)по его позициям корзины - оставить только клиентов с итогом
>= 1000 - порог по итогу — фильтр после агрегации, а не по строкам
- сортировка по итогу по убыванию, не более 10 строк
SELECT customer.id, customer.email
FROM customer
-- ваш запрос здесь
Напишите запрос.
Отфильтруйте RU-строки в WHERE country = 'ru', сделайте GROUP BY customer.id, email, затем суммируйте каждую корзину через SUM(amount * price). HAVING отбирает группы с итогом >= 1000 (он работает после агрегации, в отличие от WHERE), ORDER BY по этой сумме DESC и LIMIT 10 оставляет верхние строки.
- ✗Помещать агрегатную проверку
SUM(...) >= 1000вWHERE, который работает до группировки и её отвергает - ✗Забывать, что каждый неагрегированный выбранный столбец должен быть в
GROUP BY - ✗Использовать
INNER JOINи молча терять RU-клиентов с пустой корзиной
- →Почему итог корзины должен быть в
HAVING, а не вWHERE? - →Как заодно вернуть число товаров каждого клиента вместе с итогом?
Оглавление
Схема
CREATE TABLE customer (
id INTEGER PRIMARY KEY,
email VARCHAR(100) NOT NULL,
country CHAR(2) NOT NULL
);
CREATE TABLE cart_item (
id INTEGER PRIMARY KEY,
customer_id INTEGER NOT NULL,
title VARCHAR(20) NOT NULL,
amount INTEGER NOT NULL,
price INTEGER NOT NULL
);
Задача: вывести id и email десяти клиентов из России (country = 'ru'), у которых суммарная стоимость корзины (SUM(amount * price)) не меньше 1000, отсортированных по этой сумме по убыванию.
Решение
SELECT customer.id, customer.email
FROM customer
LEFT JOIN cart_item ON cart_item.customer_id = customer.id
WHERE customer.country = 'ru'
GROUP BY customer.id, customer.email
HAVING SUM(cart_item.amount * cart_item.price) >= 1000
ORDER BY SUM(cart_item.amount * cart_item.price) DESC
LIMIT 10;
Ключевые моменты:
и отсеется в HAVING (порог >= 1000 ложен для NULL).
WHEREотбирает строки до группировки, поэтому фильтр по стране стоит здесь.HAVINGотбирает группы после агрегации — только так можно сравнитьSUM(...).- В
SELECTбез агрегатной функции допустимы лишь столбцы изGROUP BY. LEFT JOINне теряет клиентов с пустой корзиной; их сумма станетNULL
Оглавление