如何使用SQL SUM窗口函数找出贡献总销售额50%的产品?
问题分析与解决方案
原SQL的错误点
- 销售额计算逻辑错误:将
orders.total_amount与item_line关联后求和,会导致订单金额被重复计算(一个订单对应多个产品行时,该订单的总金额会被每个产品行累加一次),完全偏离了产品实际销售额(应为quantity * unit_price的总和)。 - HAVING条件逻辑矛盾:
SUM(o.total_amount) = SUM(o.total_amount)*0.5仅当销售额为0时成立,完全不符合“找出贡献总销售额50%的产品”的需求。
正确的窗口函数实现方案
我们需要按产品销售额从高到低排序,找出累计贡献达到总销售额50%的产品集合(即帕累托分析中Top N产品覆盖50%营收的场景)。以下是具体SQL:
WITH product_sales AS ( -- 第一步:计算每个产品的总销售额 SELECT product_name, SUM(quantity * unit_price) AS product_revenue FROM item_line GROUP BY product_name ), cumulative_sales AS ( -- 第二步:计算总销售额、累计销售额及累计占比 SELECT product_name, product_revenue, SUM(product_revenue) OVER () AS total_revenue, SUM(product_revenue) OVER (ORDER BY product_revenue DESC) AS cumulative_revenue, -- 计算累计占比 ROUND( SUM(product_revenue) OVER (ORDER BY product_revenue DESC) / SUM(product_revenue) OVER () * 100, 2 ) AS cumulative_percent FROM product_sales ) -- 第三步:筛选出累计贡献达到或覆盖50%销售额的产品 SELECT product_name, product_revenue, cumulative_percent FROM cumulative_sales WHERE -- 累计额未超过50%的产品,或者当前产品是让累计额首次跨过50%的那个产品 cumulative_revenue <= total_revenue * 0.5 OR (cumulative_revenue - product_revenue) < total_revenue * 0.5 ORDER BY product_revenue DESC;
执行结果说明
根据提供的数据:
- 总销售额为
(4*100+5*10)+(150*10) = 450 + 1500 = 1950 - Coke的销售额为1550,占比约79.49%,单独就超过了50%,所以最终结果只会返回Coke。
内容的提问来源于stack exchange,提问作者Atif
相关产品推荐
相关产品推荐

