130 lines
4.7 KiB
SQL
130 lines
4.7 KiB
SQL
-- Задание 1
|
|
SELECT
|
|
category,
|
|
count(*) products_count
|
|
FROM
|
|
mnoskov.products
|
|
GROUP BY
|
|
category
|
|
ORDER BY
|
|
products_count;
|
|
-- Если убрать order by, то статистика будет в случайном разрбосанном виде, а не по возрастанию
|
|
-- Увеличится products_count на одно значение
|
|
|
|
|
|
-- Задание 2
|
|
SELECT
|
|
order_id,
|
|
sum(quantity) AS total_quantity,
|
|
sum(quantity * price_at_purchase) AS order_revenue
|
|
FROM
|
|
mnoskov.order_items
|
|
GROUP BY
|
|
order_id
|
|
ORDER BY
|
|
order_revenue DESC;
|
|
-- Если убрать GROUP BY, то будет ошибка
|
|
-- Нельзя просто добавить в SELECT ещё одну колонку (например, product_id) без добавления её в GROUP BY или агрегат, потому что вылезет ошибка. Ну и колонка должна быть либо сгруппирована либо в агрегате, она не может существовать сама по себе в запросе с grouup by
|
|
|
|
|
|
-- Задание 3
|
|
SELECT
|
|
p.category,
|
|
sum(oi.quantity * oi.price_at_purchase) AS category_revenue
|
|
FROM
|
|
mnoskov.order_items oi
|
|
JOIN
|
|
mnoskov.products p ON oi.product_id = p.id
|
|
GROUP BY
|
|
p.category
|
|
ORDER BY
|
|
category_revenue DESC;
|
|
-- Группировка по p.category - потому что мы хотим узнать сумму прибли по каждой категории
|
|
-- Если добавить p.name - будет ошибка потому что p.name тоже нужно будет заносить в GROUP BY
|
|
|
|
|
|
-- Задание 4
|
|
SELECT
|
|
oi.order_id,
|
|
sum(oi.quantity * oi.price_at_purchase) AS order_revenue
|
|
FROM
|
|
mnoskov.orders o
|
|
JOIN
|
|
mnoskov.order_items oi ON o.id = oi.order_id
|
|
WHERE
|
|
o.status = 'paid'
|
|
GROUP BY
|
|
oi.order_id
|
|
ORDER BY
|
|
order_revenue DESC;
|
|
-- В задаче-2 были все заказы, а тут только оплаченные
|
|
-- Я бы смотрел толлько на paid, чтобы понять прибыль которая уже есть
|
|
|
|
|
|
-- Задание 5
|
|
SELECT
|
|
p.category,
|
|
sum(oi.quantity * oi.price_at_purchase) AS category_revenue
|
|
FROM
|
|
mnoskov.order_items oi
|
|
JOIN
|
|
mnoskov.products p ON oi.product_id = p.id
|
|
GROUP BY
|
|
p.category
|
|
HAVING
|
|
sum(oi.quantity * oi.price_at_purchase) > 1000
|
|
ORDER BY
|
|
category_revenue DESC;
|
|
-- Если добавить это условие в WHERE, то терминал будет ругаться мол агрегаты недопустимы в WHERE
|
|
-- Обычно условие(прим: WHERE price > 1000) отличается от агрегированного условия(прим: HAVING SUM(...) > 1000) тем, что в первом случае ничего считать не нужно, значение уже есть, а во втором нужно сначала чтобы функция все посчитала. Ну и HAVING запускается уже после группировки
|
|
|
|
|
|
-- Задание 6
|
|
SELECT
|
|
country,
|
|
count(*) AS active_user_count
|
|
FROM
|
|
mnoskov.users
|
|
WHERE
|
|
is_active = true
|
|
GROUP BY
|
|
country
|
|
HAVING
|
|
count(*) >= 2
|
|
ORDER BY
|
|
active_user_count DESC;
|
|
-- is_active = true логичнее писать в WHERE, потому что is_active - не агрегат
|
|
-- Если нет страны где больше двух активных юзеров, то ничего не выведется
|
|
|
|
|
|
-- Задание 7
|
|
SELECT
|
|
p.name AS product_name,
|
|
sum(oi.quantity) AS total_quantity_sold
|
|
FROM
|
|
mnoskov.order_items oi
|
|
JOIN
|
|
mnoskov.products p ON oi.product_id = p.id
|
|
GROUP BY
|
|
p.name
|
|
ORDER BY
|
|
total_quantity_sold DESC
|
|
LIMIT 3;
|
|
-- total_quantity_sold - количество проданного товара, а product_revenue - выручка каждого товара
|
|
-- Бизнес сморит на количество, может быть когда товара очень много и нужно понять какой % уже продан, и когда нужно найти популярные или непопулярные товары
|
|
|
|
|
|
-- Задание 8
|
|
SELECT
|
|
order_id,
|
|
sum(quantity * price_at_purchase) AS order_revenue
|
|
FROM
|
|
mnoskov.order_items
|
|
GROUP BY
|
|
order_id
|
|
HAVING
|
|
sum(quantity * price_at_purchase) < 10000
|
|
ORDER BY
|
|
order_revenue;
|
|
-- Не понял вопрос: Какие реальные причины могут быть у очень маленьких заказов (1–2 гипотезы)? Ответ: «доставка пробников/тестовой партии», «использование купонов/бонусов», «технический тест витрины»
|
|
-- Проще увидеть глазами отфильтрованные микро-заказы |