SQL如何关联两张表 按客户分组取销售额Top5的客户数据
实现说明
需求为关联sales.customers和sales.transactions两张表,按客户名称分组,筛选销售额最高的前5个客户。
原代码存在的问题
- 缺少分组聚合逻辑:没有按客户维度汇总销售金额,直接读取交易明细的单笔销售额,无法得到每个客户的总销售数据
- 窗口函数分区逻辑错误:
partition by custmer_name的写法是对每个客户自身的交易记录做组内排序,无法实现不同客户之间的销售额横向对比排名 - 缺少最终筛选逻辑:仅计算了排名值,没有针对排名结果做筛选,也没有做全局排序
正确SQL实现
方案1:直接取销售额前5(无并列处理,性能最优)
适合不需要保留并列第五客户的场景,执行效率最高:
WITH customer_sales AS ( SELECT c.custmer_name, SUM(t.sales_amount) AS total_sales_amount FROM sales.customers c INNER JOIN sales.transactions t ON c.customer_code = t.customer_code GROUP BY c.custmer_name ) SELECT custmer_name, total_sales_amount FROM customer_sales ORDER BY total_sales_amount DESC LIMIT 5;
方案2:保留并列排名(用dense_rank实现)
如果存在多个客户销售额并列第五的情况,会将所有符合排名要求的客户全部返回,不会截断:
WITH customer_sales AS ( SELECT c.custmer_name, SUM(t.sales_amount) AS total_sales_amount FROM sales.customers c INNER JOIN sales.transactions t ON c.customer_code = t.customer_code GROUP BY c.custmer_name ), sales_rank AS ( SELECT custmer_name, total_sales_amount, DENSE_RANK() OVER(ORDER BY total_sales_amount DESC) AS sales_ranking FROM customer_sales ) SELECT custmer_name, total_sales_amount FROM sales_rank WHERE sales_ranking <= 5;
注意:这里窗口函数不需要加
PARTITION BY子句,因为要对所有客户的总销售额做全局排序,而非分组内排序。
内容的提问来源于stack exchange,提问作者JACK
相关产品推荐
相关产品推荐

