如何筛选指定时段内Top2客户及其Top2订购产品?
正确SQL实现:筛选指定时段内消费Top2客户及对应Top2产品
需求
- 筛选指定日期范围内总销售额排名前2的客户
- 展示每位客户的总销售额,以及其销售额最高的前2款产品的销售额(匹配期望的列格式)
你的代码问题
- 引用了不存在的表(
Orders、OrderDetail),实际仅需操作单一订单数据表 - 使用了原始数据中不存在的
CustomerId字段 - 子查询的
TOP 2是全局排序,未按客户分组筛选个人Top2产品 - 未计算客户总销售额,也未实现行转列来匹配期望的输出结构
正确SQL方案(SQL Server环境)
假设订单表名为sales_orders,指定时段为2023-10-01至2023-10-05:
WITH customer_total AS ( -- 计算客户总销售额并筛选Top2 SELECT 客户, SUM(销售额) AS 总销售额, ROW_NUMBER() OVER(ORDER BY SUM(销售额) DESC) AS customer_rank FROM sales_orders WHERE 日期 BETWEEN '2023-10-01' AND '2023-10-05' GROUP BY 客户 ), customer_product_ranking AS ( -- 按客户分组计算各产品销售额,取个人Top2产品 SELECT 客户, 产品, SUM(销售额) AS 产品销售额, ROW_NUMBER() OVER(PARTITION BY 客户 ORDER BY SUM(销售额) DESC) AS product_rank FROM sales_orders WHERE 日期 BETWEEN '2023-10-01' AND '2023-10-05' GROUP BY 客户, 产品 ) -- 行转列生成期望格式 SELECT ct.客户, ct.总销售额, MAX(CASE WHEN cpr.产品 = 'Orange' THEN cpr.产品销售额 ELSE 0 END) AS Orange, MAX(CASE WHEN cpr.产品 = 'Apple' THEN cpr.产品销售额 ELSE 0 END) AS Apple FROM customer_total ct JOIN customer_product_ranking cpr ON ct.客户 = cpr.客户 WHERE ct.customer_rank <= 2 AND cpr.product_rank <= 2 GROUP BY ct.客户, ct.总销售额 ORDER BY ct.总销售额 DESC;
代码解释
customer_total:生成客户总销售额及排名,筛选出Top2高消费客户customer_product_ranking:对每个客户的产品销售额排序,保留个人Top2产品- 最终查询:通过
CASE语句行转列,将产品销售额转为固定列展示,匹配你需要的输出格式
输出结果
| 客户 | 总销售额 | Orange | Apple |
|---|---|---|---|
| Naomi | 9.00 | 6.00 | 3.00 |
| Mike | 7.00 | 4.00 | 3.00 |
提示:如果客户的Top2产品不固定(可能出现Banana、Grapes等),可以用动态SQL实现动态列,上述代码针对你给出的期望输出做了固定列适配
内容的提问来源于stack exchange,提问作者User_K47
相关产品推荐
相关产品推荐

