-- Задание 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; -- По такому графику мы можем видеть РОСТ выручки по дням например, а не просто сколько в какой день принесла категория