You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

SQL查询需求:按客户筛选对应最高营收的日期(修正现有查询)

解决每个客户最高营收对应日期的筛选问题

嗨,我懂你现在的困扰——之前的查询只能算出每个客户每天的最高营收,但你真正要的是定位到每个客户营收最高的那一天(或几天)。这里给你两种常用的解决方案,适配不同的数据库和场景:

方案1:使用窗口函数(推荐,支持PostgreSQL、MySQL 8+、SQL Server等)

窗口函数是处理这类分组Top N问题最简洁的方式,根据你是否需要保留并列最高的记录,可以选两种函数:

场景A:只取每个客户最高营收的一条记录(若有并列,按日期排序取其一)

ROW_NUMBER()给每个客户的记录按营收降序、日期升序(或降序)编号,然后取编号为1的记录:

WITH ranked_revenue AS (
    SELECT 
        customer_id,
        revenue_date,
        daily_revenue,
        ROW_NUMBER() OVER (
            PARTITION BY customer_id 
            ORDER BY daily_revenue DESC, revenue_date ASC
        ) AS rn
    FROM customer_revenue
)
SELECT customer_id, revenue_date, daily_revenue
FROM ranked_revenue
WHERE rn = 1;
  • PARTITION BY customer_id:按客户分组
  • ORDER BY daily_revenue DESC:每组内按营收从高到低排序
  • 额外加revenue_date ASC是为了当营收相同时,取最早的那一天(你也可以改成DESC取最晚的)

场景B:保留每个客户所有营收并列最高的日期

如果同一个客户有多天营收都是最高值,用RANK()函数可以把这些记录都保留下来:

WITH ranked_revenue AS (
    SELECT 
        customer_id,
        revenue_date,
        daily_revenue,
        RANK() OVER (
            PARTITION BY customer_id 
            ORDER BY daily_revenue DESC
        ) AS rnk
    FROM customer_revenue
)
SELECT customer_id, revenue_date, daily_revenue
FROM ranked_revenue
WHERE rnk = 1;

ROW_NUMBER()不同,RANK()会给并列的记录分配相同的排名,所以所有最高营收的日期都会被筛选出来。

方案2:子查询关联(兼容老版本数据库,如MySQL 5.x)

如果你的数据库不支持窗口函数,可以先查询每个客户的最高营收值,再关联原表找到对应的日期:

SELECT cr.customer_id, cr.revenue_date, cr.daily_revenue
FROM customer_revenue cr
JOIN (
    SELECT customer_id, MAX(daily_revenue) AS max_revenue
    FROM customer_revenue
    GROUP BY customer_id
) cr_max ON cr.customer_id = cr_max.customer_id 
    AND cr.daily_revenue = cr_max.max_revenue;

这个方法同样会保留所有营收等于最高值的日期,和RANK()的效果一致。

注意:如果你的表中有重复的(customer_id, revenue_date)记录,可能需要根据实际情况加DISTINCT去重。

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

火山引擎 最新活动