如何通过Oracle SQL的CONNECT BY函数生成15分钟间隔时间输出?
Oracle SQL 生成15分钟区间结束时间的问题修正
你的SQL主要存在4个问题,以下是具体分析和修正方案:
错误点分析
- 初始时间计算偏差:你需要的是区间结束时间,第一个结束时间应为
START_DATE + 15分钟,但原SQL中START_DATE + ((LEVEL - 1)/96)会从START_DATE本身(10:30)开始,不符合需求。 - CONNECT BY 无防笛卡尔积/循环条件:未添加PRIOR关联条件时,单表多行或单行都会出现逻辑错误,导致数据重复或递归循环。
- 层级数量计算错误:原公式
((END_DATE - START_DATE)*96) +1会多生成一行(示例中会得到6行而非需要的5行),因为(END_DATE - START_DATE)*96已经等于区间总数。 - 使用关键字作为表名:
table是Oracle保留关键字,不能直接作为表名使用。
修正方案
方案1:修正CONNECT BY写法
WITH interval_data AS ( SELECT START_DATE + (LEVEL / 96) AS quarter_hour, -- 从START_DATE+15分钟开始生成结束时间 VALUE FROM your_table -- 替换为你的实际表名 CONNECT BY LEVEL <= (END_DATE - START_DATE) * 96 -- 精准计算需要生成的区间数量 AND PRIOR ID = ID -- 确保仅针对当前行递归,避免笛卡尔积 AND PRIOR SYS_GUID() IS NOT NULL -- 防止递归循环报错 ) SELECT TO_CHAR(quarter_hour, 'DD.MM.YYYY HH24:MI') AS quarter_hour, VALUE FROM interval_data ORDER BY quarter_hour;
方案2:使用递归CTE(更易读,Oracle 11g R2+支持)
WITH interval_data (quarter_hour, end_date, value) AS ( -- 初始行:生成第一个区间结束时间 SELECT start_date + INTERVAL '15' MINUTE, end_date, value FROM your_table -- 替换为你的实际表名 UNION ALL -- 递归生成后续区间 SELECT quarter_hour + INTERVAL '15' MINUTE, end_date, value FROM interval_data WHERE quarter_hour < end_date -- 直到达到设定的结束时间 ) SELECT TO_CHAR(quarter_hour, 'DD.MM.YYYY HH24:MI') AS quarter_hour, value FROM interval_data ORDER BY quarter_hour;
两种方案都能生成你需要的结果:
| QUARTER_HOUR | VALUE |
|---|---|
| 14.07.2022 10:45:00 | N |
| 14.07.2022 11:00:00 | N |
| 14.07.2022 11:15:00 | N |
| 14.07.2022 11:30:00 | N |
| 14.07.2022 11:45:00 | N |
内容的提问来源于stack exchange,提问作者Paul Wegen
相关产品推荐
相关产品推荐

