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

如何用Oracle SQL按24小时拆分时长区间并生成明细行

Oracle SQL拆分时间区间为按日分段

原表结构与数据

ID | STARTDATE                | ENDDATE                  | Status
---+--------------------------+--------------------------+--------
1  | 2024-02-01 08:00:00.000  | 2024-02-02 10:30:00.000  | a
1  | 2024-02-02 10:30:00.000  | 2024-02-05 14:20:00.000  | b
1  | 2024-02-05 14:20:00.000  | 2024-02-07 08:15:00.000  | c

期望输出

ID | STARTDATE                | ENDDATE                 | Status
---+--------------------------+-------------------------+--------
1  | 2024-02-01 08:00:00.000  | 2024-02-02 00:00:00.000 | a 
1  | 2024-02-02 00:00:00.000  | 2024-02-02 10:30:00.000 | a
1  | 2024-02-02 10:30:00.000  | 2024-02-03 00:00:00.000 | b
1  | 2024-02-03 00:00:00.000  | 2024-02-04 00:00:00.000 | b
1  | 2024-02-04 00:00:00.000  | 2024-02-05 00:00:00.000 | b
1  | 2024-02-05 00:00:00.000  | 2024-02-05 14:20:00.000 | b 
1  | 2024-02-05 14:20:00.000  | 2024-02-06 00:00:00.000 | c
1  | 2024-02-06 00:00:00.000  | 2024-02-07 00:00:00.000 | c
1  | 2024-02-07 00:00:00.000  | 2024-02-07 08:15:00.000 | c

解决方案

使用Oracle的**递归CTE(Common Table Expression)**可以实现该需求,核心逻辑是递归生成每个时间区间内的每日分段:

WITH time_segments AS (
    -- 初始段:处理从原起始时间到当日午夜的分段
    SELECT 
        ID,
        STARTDATE AS seg_start,
        TRUNC(STARTDATE) + 1 AS seg_end,
        ENDDATE AS original_end,
        Status
    FROM your_table
    WHERE STARTDATE < TRUNC(STARTDATE) + 1

    UNION ALL

    -- 递归生成后续分段:完整整天或最后一段到原结束时间
    SELECT 
        ID,
        seg_end AS seg_start,
        CASE 
            WHEN TRUNC(seg_end) + 1 < original_end THEN TRUNC(seg_end) + 1
            ELSE original_end
        END AS seg_end,
        original_end,
        Status
    FROM time_segments
    WHERE seg_end < original_end
)
-- 整理输出结果并排序
SELECT 
    ID,
    seg_start AS STARTDATE,
    seg_end AS ENDDATE,
    Status
FROM time_segments
ORDER BY ID, seg_start;

代码说明

  1. 初始CTE:针对每条记录,生成从原STARTDATE到当日午夜的第一段数据,若原起始时间恰好是午夜,这部分不会生成记录,由递归逻辑处理。
  2. 递归逻辑:
    • 以上一段的结束时间作为下一段的起始时间。
    • 若下一段的午夜时间早于原ENDDATE,则生成完整整天的分段;否则生成到原ENDDATE的最后一段。
  3. 最终查询:按ID和分段起始时间排序,输出符合要求的拆分结果。

注意事项

  • 将代码中的your_table替换为实际表名。
  • 确保STARTDATE和ENDDATE字段为DATE或TIMESTAMP类型,Oracle的TRUNC函数对这两种类型均兼容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 19:16:29