homework, pet project DE Dmitry_Medvedev #1

Open
dmitry_medvedev wants to merge 264 commits from md_branch into main
Showing only changes of commit 4b96e6012f - Show all commits
@@ -0,0 +1,168 @@
-- Задание 1
SELECT
o.user_id,
u.name AS user_name,
o.id AS order_id,
o.order_date::date,
row_number() OVER (PARTITION BY o.user_id ORDER BY o.order_date) AS order_number_for_user
FROM
mnoskov.orders o
JOIN
mnoskov.users u ON o.user_id = u.id;
-- Отличае от обычного order by в том, что мы не просто сортируем, а сортируем в пределах одного пользователя, и ещё выводим нумерацию заказов
-- Задание 2
WITH order_total_revenue AS (
SELECT
o.user_id,
oi.order_id,
o.order_date::date,
sum(oi.quantity * oi.price_at_purchase) AS order_revenue
FROM
mnoskov.order_items oi
JOIN
mnoskov.orders o ON oi.order_id = o.id
GROUP BY
o.user_id, oi.order_id, o.order_date
)
SELECT
otr.user_id,
u.name AS user_name,
otr.order_id,
otr.order_date::date,
otr.order_revenue,
sum(otr.order_revenue) OVER (PARTITION BY otr.user_id ORDER BY otr.order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS running_revenue_for_user
FROM
mnoskov.users u
JOIN
order_total_revenue otr ON u.id = otr.user_id;
-- Если не задвать рамку, то могут пояиться проблемы с дубликатами
-- Если накопительная выручка пользователя становится больше, значит он начинает тратить больше
-- Задание 3
WITH user_total_revenue AS (
SELECT
o.user_id,
sum(oi.quantity * oi.price_at_purchase) AS total_revenue
FROM
mnoskov.orders o
JOIN
mnoskov.order_items oi ON o.id = oi.order_id
GROUP BY
o.user_id
)
SELECT
u.name AS user_name,
utr.total_revenue,
rank() OVER (ORDER BY utr.total_revenue) AS revenue_rank,
dense_rank() OVER (ORDER BY utr.total_revenue) AS revenue_dense_rank
FROM
mnoskov.users u
JOIN
user_total_revenue utr ON u.id = utr.user_id;
-- Когда появляется одинаковая выручка, dense_rank нумерует по порядку, без пропусков(1,2,2,3), а rank по 'расположению'(1,2,2,4)
-- Задание 4
SELECT
u.name AS user_name,
o.id AS order_id,
o.order_date::date,
first_value(o.order_date::date) OVER (PARTITION BY u.id ORDER BY o.order_date) AS first_order_date,
last_value(o.order_date::date) OVER (PARTITION BY u.id ORDER BY o.order_date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS last_order_date
FROM
mnoskov.orders o
JOIN
mnoskov.users u ON o.user_id = u.id;
-- Первый заказ можно использовать для отчета 'как давно клиент начал активничать', а последний заказ, например если давно был последний заказ, то кинуть рассылку с промокодом, чтобы клиент снова начала заказывать как вариант
-- Если не задать рамку, то дата последнего заказа будет равна текущей строке, а не последней
-- Задание 5
SELECT
u.name AS user_name,
o.id AS order_id,
count(*) OVER (PARTITION BY u.id) AS orders_per_user
FROM
mnoskov.orders o
JOIN
mnoskov.users u ON o.user_id = u.id;
-- Если использовать просто group by, то пользователи сожмутся в одну ячейку
-- Задание 6
WITH order_total_revenue AS (
SELECT
o.user_id,
oi.order_id,
o.order_date::date,
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
GROUP BY
o.user_id, oi.order_id, o.order_date
)
SELECT
u.name AS user_name,
otr.order_id,
otr.order_date::date,
otr.order_revenue,
lag(otr.order_revenue) OVER (PARTITION BY u.id ORDER BY otr.order_date) AS prev_order_revenue
FROM
mnoskov.users u
JOIN
order_total_revenue otr ON u.id = otr.user_id;
-- если текущее значение среднего чека больше чем предидущие, то увеличивается, а если наоборот, то уменьшается
-- Задание 7
-- По месяцам:
WITH category_total_revenue AS (
SELECT
p.category,
date_trunc('month', o.order_date)::date AS order_date_month,
sum(oi.quantity * oi.price_at_purchase) AS monthly_category_revenue
FROM
mnoskov.products p
JOIN
mnoskov.order_items oi ON p.id = oi.product_id
JOIN
mnoskov.orders o ON oi.order_id = o.id
GROUP BY
p.category, order_date_month
)
SELECT
category,
order_date_month,
monthly_category_revenue,
sum(monthly_category_revenue) OVER (PARTITION BY category ORDER BY order_date_month ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS running_category_revenue
FROM
category_total_revenue;
-- По дням:
WITH category_total_revenue AS (
SELECT
p.category,
o.order_date::date AS order_date,
sum(oi.quantity * oi.price_at_purchase) AS daily_category_revenue
FROM
mnoskov.products p
JOIN
mnoskov.order_items oi ON p.id = oi.product_id
JOIN
mnoskov.orders o ON oi.order_id = o.id
GROUP BY
p.category, order_date
)
SELECT
category,
order_date,
daily_category_revenue,
sum(daily_category_revenue) OVER (PARTITION BY category ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS running_category_revenue
FROM
category_total_revenue;
-- По такому графику мы можем видеть РОСТ выручки по дням например, а не просто сколько в какой день принесла категория