SQL |如何对 3 个项目的分区组求和?

SQL | How to sum over partition group of 3 items?

我正在尝试获取前 3 个产品类别的一天收入的百分比,但很难计算出该百分比。我已经知道每个产品的收入排名 1 到 3,但我不知道如何获得百分比。

任何指点将不胜感激。

SELECT * FROM (
SELECT   date, 
         category_name,
         revenue,
         row_number() OVER(PARTITION BY DATE(date) ORDER BY revenue DESC) AS category_rank,
         (revenue / (select sum(revenue) from a group by 1)) * 100 percentage AS percentage_of_daily_total -- this is the wrong one 

  FROM (
    SELECT DATE(orders.order_timestamp) AS date,
           products.product_cat AS category_name,
           ROUND(SUM(payments.payment)) AS revenue
    FROM table1.orders orders
    JOIN table1.t_payments payments ON orders.order_id = payments.order_id
    JOIN table1.t_items items ON orders.order_id = items.order_id
    JOIN table1.t_products products ON items.product_id = products.product_id
    GROUP BY 1 ,2) a) b
WHERE category_rank <= 3;

示例数据如下:日期,category_name,收入,category_rank

2016-10-05  jeans       20  1
2016-10-05  shirts      15  2
2016-10-05  shoes       10  3
2016-10-06  skirts      50  1
2016-10-06  sports_wear 30  2
2016-10-06  accesories  10  3

期望 outcome:date、category_name、收入、category_rank、percentage_of_daily_total

2016-10-05  jeans       30  1  50
2016-10-05  shirts      20  2  33
2016-10-05  shoes       10  3  17
2016-10-06  skirts      20  1  50 
2016-10-06  sports_wear 16  2  40
2016-10-06  accessories 4   3  10

使用CTEs

WITH a AS (
    SELECT DATE(orders.order_timestamp) AS date,
           products.product_cat AS category_name,
           ROUND(SUM(payments.payment)) AS revenue
    FROM table1.orders orders
    JOIN table1.t_payments payments ON orders.order_id = payments.order_id
    JOIN table1.t_items items ON orders.order_id = items.order_id
    JOIN table1.t_products products ON items.product_id = products.product_id
    GROUP BY 1 ,2
)

SELECT * FROM (
SELECT   a.date, 
         a.category_name,
         a.revenue,
         row_number() OVER(PARTITION BY DATE(a.date) ORDER BY a.revenue DESC) AS category_rank,
         (a.revenue / b.revenue_sum) * 100 percentage AS percentage_of_daily_total
  FROM a
  JOIN (SELECT date, sum(revenue) AS revenue_sum FROM a GROUP BY 1) AS b
  ON a.date = b.date)
WHERE category_rank <= 3;

您的原始查询非常接近。计算 OUTERMOST sql 中的百分比。所以放下你的百分比计算然后在外部 Select:

Select *, 100*revenue/(sum(revenue) Over (Partition by Date)) as percentage_of_daily_total

请记住,当您开始计算窗口函数时,Where 子句已经执行,并且您每天只有 3 条记录,因此任何总数都将仅基于前 3 条。