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

如何使用Partition并保持编号连续性?非工作日日期编号需求及SQL实现咨询

解决日期编号需求:非工作日继承前一个编号,工作日连续递增

嘿,我来帮你搞定这个编号问题!你当前写的Rank() Over(PARTITION BY Working_Day ORDER BY TheDate)其实走偏了——它会把工作日和非工作日分成两个独立的分组分别排名,导致工作日和非工作日各自从1开始计数,完全不符合你要的“非工作日继承前一个日期编号”的需求。

核心思路

我们需要的逻辑是:每遇到一个工作日,编号就递增1;非工作日的编号和前一个日期保持一致,且编号从1开始。实现这个的关键是累计统计当前日期及之前的工作日总数,再处理初始无工作日的情况即可。

具体SQL实现

根据你的working_day字段类型,分两种情况给出代码:

情况1:working_day是数值类型(1=工作日,0=非工作日)

SELECT 
    thedate,
    working_day,
    -- 累计工作日数,若还没出现过工作日则编号为1,否则用累计数作为编号
    CASE 
        WHEN SUM(working_day) OVER (ORDER BY thedate) = 0 
        THEN 1 
        ELSE SUM(working_day) OVER (ORDER BY thedate) 
    END AS desired_number
FROM CAL
ORDER BY thedate;

情况2:working_day是字符类型('Y'=工作日,'N'=非工作日)

SELECT 
    thedate,
    working_day,
    CASE 
        WHEN SUM(CASE WHEN working_day = 'Y' THEN 1 ELSE 0 END) OVER (ORDER BY thedate) = 0 
        THEN 1 
        ELSE SUM(CASE WHEN working_day = 'Y' THEN 1 ELSE 0 END) OVER (ORDER BY thedate) 
    END AS desired_number
FROM CAL
ORDER BY thedate;

逻辑解释

  • SUM(...) OVER (ORDER BY thedate):这个窗口函数会按日期顺序,累计计算到当前日期为止的工作日数量。工作日贡献1,非工作日贡献0。
  • CASE语句:处理初始状态——如果当前日期及之前还没有任何工作日(累计数为0),编号设为1;否则直接用累计的工作日数作为编号,这样工作日会连续递增,非工作日则继承前一个工作日的编号。

示例验证

假设你的CAL表有以下数据:

thedateworking_day
1982-01-010
1982-01-020
1982-01-031
1982-01-041
1982-01-050
1982-01-061

运行SQL后会得到:

thedateworking_daydesired_number
1982-01-0101
1982-01-0201
1982-01-0311
1982-01-0412
1982-01-0502
1982-01-0613

完全符合你预期的编号规则!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 04:14:09