homework, pet project DE Dmitry_Medvedev #1
@@ -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;
|
||||
-- По такому графику мы можем видеть РОСТ выручки по дням например, а не просто сколько в какой день принесла категория
|
||||
Reference in New Issue
Block a user