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

使用row_number() OVER (partition BY时阈值达标排序结果不符合预期问题

问题分析

你当前的SQL逻辑存在核心问题:row_number()是在整个product_name, userid分区内计算所有行的行号,之后仅通过case将未达标行的结果替换为0,但达标行仍然保留了全局行号(比如第三行是整个分区的第3行,所以显示3),这就导致达标后的序号没有从1开始递增。

解决方案

要实现「首次达标行显示1,后续达标行依次递增,未达标行显示0」的需求,需要先标记出达标阶段的行,再对这些行单独计算序号。以下提供两种简洁的实现方式:

方式一:累计标记+分区行号

先通过窗口函数标记是否进入达标阶段,再对达标阶段的行单独计数:

select 
    date, 
    cost_amt, 
    cumulative_cost,
    case 
        when has_reached = 1 then 
            row_number() over(partition by product_name, userid, has_reached order by date, order_id) 
        else 0 
    end as threshold_reached_order,
    product_id
from (
    select 
        date, 
        cost_amt, 
        cumulative_cost,
        product_name,
        userid,
        product_id,
        -- 标记当前行及之前是否已达标,一旦达标后续行均为1
        max(case when cumulative_cost >= threshold then 1 else 0 end) 
            over(partition by product_name, userid order by date, order_id rows unbounded preceding) as has_reached
    from table1
    where userid = 'ABCDEFG'
) t
order by userid, product_id;

方式二:直接累计达标行数

由于cumulative_cost是累加值,一旦达标后续行必然满足cumulative_cost >= threshold,因此可以直接累计达标行的数量:

select 
    date, 
    cost_amt, 
    cumulative_cost,
    case 
        when cumulative_cost >= threshold then 
            sum(case when cumulative_cost >= threshold then 1 else 0 end) 
                over(partition by product_name, userid order by date, order_id)
        else 0 
    end as threshold_reached_order,
    product_id
from table1
where userid = 'ABCDEFG'
order by userid, product_id;
效果验证

执行上述任意方案后,结果将符合你的预期:

datecost_amtcumulative_costthreshold_reached_orderproduct_id
9/07/202314.0914.09012345
9/07/202310.224.29012345
9/07/202325.0349.32112345
11/07/202328.0977.41212345

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 21:55:59