Обновить
1

Пользователь

Отправить сообщение

В "Задача 4. Кумулятивные продажи с детализацией (динамика во времени) простой вариант" вы наступаете на те же грабли, не обозначив фрейм для рассчета cumulative_revenue. На примере pharmacy_id =1 это хорошо видно. Так как в 2026-02-01 есть две продажи, а фрейм явно не указан (по умолчанию postgres берет range between). Поэтому для обеих продаж нет нарастания, а дана общая сумма.

В примере с АВС анализом, для подсчета нарастающего итога вы используете row_number(), хотя можно было сразу его посчитать, добавив фрейм окна в виде ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW. Тогда в CTE второе выражение не потребовалось бы

WITH product_sales AS (

SELECT

pr.product_id,

pr.product_name,

pr.category,

SUM(s.amount) AS revenue,

SUM(SUM(s.amount)) OVER() AS total_revenue,

SUM(SUM(s.amount)) OVER(order BY SUM(s.amount) desc rows between unbounded preceding and current row) as cumulative_revenue

-- ROW_NUMBER() OVER(ORDER BY SUM(s.amount) DESC) AS revenue_rank

FROM sales s

JOIN products pr ON s.product_id = pr.product_id

GROUP BY pr.product_id, pr.product_name, pr.category

)

/*cumulative_calc AS (

SELECT

product_id,

product_name,

category,

revenue,

revenue_rank,

SUM(revenue) OVER(ORDER BY revenue_rank) AS cumulative_revenue,

total_revenue

FROM product_sales

)*/

SELECT

product_name,

category,

revenue,

ROUND(100.0 * revenue / total_revenue, 2) AS revenue_share,

ROUND(100.0 * cumulative_revenue / total_revenue, 2) AS cumulative_share,

CASE

WHEN cumulative_revenue <= 0.7 * total_revenue THEN 'A'

WHEN cumulative_revenue <= 0.9 * total_revenue THEN 'B'

ELSE 'C'

END AS abc_class

FROM product_sales

ORDER BY revenue desc

;

Информация

В рейтинге
7 593-й
Зарегистрирован
Активность

Специализация

Аналитик по данным, Инженер по данным
Стажёр
SQL
Python