You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何按规则将TOP3值转为3列?求各客户各销售月TOP3卖家SQL方案

解决方案:获取每个客户每月金额TOP3商品并转为多列

嘿,你已经迈出了关键的第一步——拿到了每个分组的第一名!要实现每个客户各销售月份金额前三的商品并转为3列的需求,我们可以通过「先筛选TOP3数据,再条件聚合转列」的思路来完成,下面是具体的SQL方案:

步骤1:获取带排名的TOP3数据集

首先我们需要给每个客户每个月的商品按金额降序排名,筛选出排名前3的记录。你用的DENSE_RANK()用法没问题,但要注意:如果有多个商品金额相同,DENSE_RANK()会给它们相同的排名(比如两个商品都是第二,下一个就是第三);如果希望即使金额相同也强制生成唯一排名,可以改用ROW_NUMBER()。

先写出带排名的子查询:

SELECT
    MONTH(Sales_Date) AS Sales_month,
    Customer_ID,
    Item,
    Amount,
    DENSE_RANK() OVER (
        PARTITION BY MONTH(Sales_Date), Customer_ID
        ORDER BY Amount DESC
    ) AS item_rank
FROM q2

这个查询会给每个Sales_month + Customer_ID分组下的商品按金额从高到低排名,我们后续只需要保留item_rank <= 3的记录。

步骤2:条件聚合将TOP3转为多列

接下来我们用条件聚合函数(比如MAX()配合CASE WHEN),把每个分组下不同排名的商品分别放到对应的列中。如果需要同时展示金额,也可以一起转换:

完整SQL代码

SELECT
    Sales_month,
    Customer_ID,
    -- 获取排名第1的商品和金额
    MAX(CASE WHEN item_rank = 1 THEN Item END) AS Top1_Item,
    MAX(CASE WHEN item_rank = 1 THEN Amount END) AS Top1_Amount,
    -- 获取排名第2的商品和金额
    MAX(CASE WHEN item_rank = 2 THEN Item END) AS Top2_Item,
    MAX(CASE WHEN item_rank = 2 THEN Amount END) AS Top2_Amount,
    -- 获取排名第3的商品和金额
    MAX(CASE WHEN item_rank = 3 THEN Item END) AS Top3_Item,
    MAX(CASE WHEN item_rank = 3 THEN Amount END) AS Top3_Amount
FROM (
    SELECT
        MONTH(Sales_Date) AS Sales_month,
        Customer_ID,
        Item,
        Amount,
        DENSE_RANK() OVER (
            PARTITION BY MONTH(Sales_Date), Customer_ID
            ORDER BY Amount DESC
        ) AS item_rank
    FROM q2
) AS ranked_items
WHERE item_rank <= 3
GROUP BY Sales_month, Customer_ID
ORDER BY Sales_month, Customer_ID;

结果说明

用你提供的样本数据运行这个SQL,会得到类似这样的结果:

Sales_monthCustomer_IDTop1_ItemTop1_AmountTop2_ItemTop2_AmountTop3_ItemTop3_Amount
7CCCNike1000NULLNULLNULLNULL
8AAAApple5600Kindle900Pear600
8BBBCola20NULLNULLNULLNULL
9BBBLEGO240NULLNULLNULLNULL
9CCCKindle5000Apple2500Nike1000

如果某个客户当月的商品不足3个,对应的列会显示NULL,这符合实际业务场景。

小提示

  • 如果你使用的是支持PIVOT语法的数据库(比如SQL Server、Oracle),也可以用PIVOT来实现转列,但CASE WHEN的写法兼容性更强,在MySQL、PostgreSQL等数据库都能运行。
  • 若要避免NULL,可以用COALESCE()函数替换MAX(),把NULL替换成你需要的默认值(比如''或'无')。

内容的提问来源于stack exchange,提问作者Jerry Lin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:17:23