Redshift SQL如何提取占销售额前80%的记录?
解决方法:无需临时表,用嵌套窗口函数或子查询即可实现
核心逻辑是:先定位每个餐厅中**累计占比首次超过80%**的那条记录的累计值,然后保留该餐厅中所有累计占比小于等于这个值的记录(包括这条首次超阈值的记录),避免出现累计仅到70%就停止的问题。
通用SQL实现(CTE版本)
WITH pizza_sales_ranked AS ( SELECT 餐厅, 披萨, 销量, -- 计算餐厅内按销量降序的累计销售占比 SUM(销量) OVER (PARTITION BY 餐厅 ORDER BY 销量 DESC) / SUM(销量) OVER (PARTITION BY 餐厅) AS running_total_sold_perc FROM 你的数据集表名 ), restaurant_threshold AS ( SELECT 餐厅, -- 取每个餐厅中首次超过0.8的最小累计占比(即第一个突破阈值的累计值) MIN(running_total_sold_perc) AS first_over_threshold FROM pizza_sales_ranked WHERE running_total_sold_perc > 0.8 GROUP BY 餐厅 ) SELECT p.* FROM pizza_sales_ranked p LEFT JOIN restaurant_threshold rt ON p.餐厅 = rt.餐厅 -- 筛选规则:若餐厅累计未达80%则全留;否则留到首次超阈值的所有记录 WHERE rt.first_over_threshold IS NULL OR p.running_total_sold_perc <= rt.first_over_threshold ORDER BY p.餐厅, p.running_total_sold_perc;
简化写法(子查询版本)
如果不想用CTE,嵌套子查询也能实现:
SELECT p.* FROM ( SELECT 餐厅, 披萨, 销量, SUM(销量) OVER (PARTITION BY 餐厅 ORDER BY 销量 DESC) / SUM(销量) OVER (PARTITION BY 餐厅) AS running_total_sold_perc FROM 你的数据集表名 ) p LEFT JOIN ( SELECT 餐厅, MIN(running_total_sold_perc) AS first_over_threshold FROM ( SELECT 餐厅, SUM(销量) OVER (PARTITION BY 餐厅 ORDER BY 销量 DESC) / SUM(销量) OVER (PARTITION BY 餐厅) AS running_total_sold_perc FROM 你的数据集表名 ) t WHERE running_total_sold_perc > 0.8 GROUP BY 餐厅 ) rt ON p.餐厅 = rt.餐厅 WHERE rt.first_over_threshold IS NULL OR p.running_total_sold_perc <= rt.first_over_threshold ORDER BY p.餐厅, p.running_total_sold_perc;
方言优化写法(支持QUALIFY子句)
如果你的SQL环境支持QUALIFY(比如BigQuery、Snowflake),可以用更简洁的写法:
SELECT 餐厅, 披萨, 销量, SUM(销量) OVER (PARTITION BY 餐厅 ORDER BY 销量 DESC) / SUM(销量) OVER (PARTITION BY 餐厅) AS running_total_sold_perc FROM 你的数据集表名 QUALIFY running_total_sold_perc <= MIN(CASE WHEN running_total_sold_perc > 0.8 THEN running_total_sold_perc END) OVER (PARTITION BY 餐厅) OR MIN(CASE WHEN running_total_sold_perc > 0.8 THEN running_total_sold_perc END) OVER (PARTITION BY 餐厅) IS NULL ORDER BY 餐厅, running_total_sold_perc;
内容的提问来源于stack exchange,提问作者Rangor
相关产品推荐
相关产品推荐

