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

如何在PL/SQL中获取分支代码变更后的起止日期极值及间隔时长

解决PL/SQL中连续分支记录的合并与日期间隔计算问题

你遇到的是典型的SQL连续分组(岛屿问题):同一个BranchCode可能非连续出现(比如示例中89出现两次,中间间隔了其他分支),直接按ID+BranchCode分区会把非连续的同分支记录合并,这就是之前结果不符合预期的原因。

以下是实现需求的PL/SQL SQL语句:

WITH branch_groups AS (
    SELECT 
        ID,
        BranchCode,
        StartDate,
        -- 把'today'转换为系统日期,方便后续计算
        CASE WHEN FinishDate = 'today' THEN SYSDATE ELSE TO_DATE(FinishDate, 'DD.MM.YYYY') END AS FinishDate,
        -- 标记新分组:当前分支与上一行不同时,标记为新组起点
        CASE 
            WHEN LAG(BranchCode) OVER (PARTITION BY ID ORDER BY TO_DATE(StartDate, 'DD.MM.YYYY')) != BranchCode 
            THEN 1 
            ELSE 0 
        END AS is_new_group,
        -- 累计生成组ID,连续相同分支会被分到同一组
        SUM(CASE 
            WHEN LAG(BranchCode) OVER (PARTITION BY ID ORDER BY TO_DATE(StartDate, 'DD.MM.YYYY')) != BranchCode 
            THEN 1 
            ELSE 0 
        END) OVER (PARTITION BY ID ORDER BY TO_DATE(StartDate, 'DD.MM.YYYY')) AS group_id
    FROM your_table_name
)
SELECT 
    ID,
    BranchCode,
    TO_CHAR(MIN(TO_DATE(StartDate, 'DD.MM.YYYY')), 'DD.MM.YYYY') AS MinStartDate,
    -- 把系统日期转回'today'显示,匹配预期输出格式
    CASE 
        WHEN MAX(FinishDate) = TRUNC(SYSDATE) THEN 'today'
        ELSE TO_CHAR(MAX(FinishDate), 'DD.MM.YYYY')
    END AS MaxFinishDate,
    -- 计算日期间隔(单位:天)
    ROUND(MAX(FinishDate) - MIN(TO_DATE(StartDate, 'DD.MM.YYYY')), 2) AS DateIntervalDays
FROM branch_groups
GROUP BY ID, BranchCode, group_id
ORDER BY MIN(TO_DATE(StartDate, 'DD.MM.YYYY'));

代码说明

  1. CTE branch_groups:
    • 先将FinishDate中的today转换为SYSDATE,统一日期格式便于计算
    • 用LAG()窗口函数对比当前行与上一行的BranchCode,标记新分组的起点
    • 通过累计求和生成group_id,让连续相同的BranchCode归为同一组
  2. 最终查询:
    • 按ID、BranchCode、group_id分组,提取每组的最小StartDate和最大FinishDate
    • 将最大日期转回today格式,同时计算两组日期的间隔天数

执行后会得到你预期的分组结果,同时新增日期间隔字段。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 19:56:19