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

如何使用MySQL查询每个客户2016年消费最高的Top3商品

解决每个客户Top3消费商品的SQL问题

我明白你的问题啦——你当前的LIMIT 3是全局范围内取前3条记录,所以只会返回第一个客户的3条数据,而不是每个客户各自取消费金额最高的3个商品。下面给你两种实用的解决方案,适配主流SQL数据库:

方法一:使用窗口函数(推荐,简洁高效)

现在几乎所有主流数据库(MySQL 8.0+、PostgreSQL、SQL Server、Oracle等)都支持窗口函数,这是解决这类分组TopN问题最优雅的方式。

完整SQL代码

SELECT customer_name, product_name, total_sum
FROM (
    SELECT 
        c.customer_name,
        p.product_name,
        s.total_sum,
        -- 按客户分组,组内按消费金额降序分配序号
        ROW_NUMBER() OVER (PARTITION BY c.customer_id ORDER BY s.total_sum DESC) AS rank_num
    FROM sales s
    JOIN customers c ON c.customer_id = s.customer_id
    JOIN products p ON p.product_id = s.product_id
    -- 筛选2016年的销售记录
    WHERE s.sale_date >= '2016-01-01' AND s.sale_date < '2017-01-01'
) ranked_sales
-- 只保留每个客户的前3条记录
WHERE rank_num <= 3
-- 按要求排序:客户名升序,消费金额降序
ORDER BY customer_name ASC, total_sum DESC;

关键部分解释

  • PARTITION BY c.customer_id:将数据按客户分组,每个客户单独计算Top3
  • ORDER BY s.total_sum DESC:在每个客户组内,按消费金额从高到低排序
  • ROW_NUMBER():给每个组内的行分配唯一序号(1、2、3...),即使金额相同也会分配不同序号

可选调整:处理并列金额

如果需要允许并列排名(比如某个客户有2个商品金额相同且都是第2名),可以替换ROW_NUMBER()为:

  • RANK():相同金额的行分配相同序号,下一个不同金额的行序号会跳号(比如两个第1,下一个是第3)
  • DENSE_RANK():相同金额的行分配相同序号,下一个不同金额的行序号连续(比如两个第1,下一个是第2)

方法二:关联子查询(适配老版本数据库)

如果你的数据库不支持窗口函数(比如MySQL 5.7及以前),可以用关联子查询实现:

完整SQL代码

SELECT 
    c.customer_name,
    p.product_name,
    s.total_sum
FROM sales s
JOIN customers c ON c.customer_id = s.customer_id
JOIN products p ON p.product_id = s.product_id
WHERE s.sale_date >= '2016-01-01' AND s.sale_date < '2017-01-01'
AND (
    -- 统计当前客户2016年消费金额大于等于当前行的记录数
    SELECT COUNT(*)
    FROM sales s2
    WHERE s2.customer_id = s.customer_id
    AND s2.sale_date >= '2016-01-01' AND s2.sale_date < '2017-01-01'
    AND s2.total_sum >= s.total_sum
) <= 3
ORDER BY c.customer_name ASC, s.total_sum DESC;

逻辑说明

子查询会计算当前客户的所有2016年销售记录中,金额大于等于当前行的记录总数。如果这个总数≤3,说明当前行属于该客户的Top3消费商品。


内容的提问来源于stack exchange,提问作者Владимир Яшин

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 16:02:47