求Oracle SQL中connect by的替代脚本(适配BI Publisher)
替代connect by的日期生成方案
以下几种方法都能实现原脚本的功能,且不依赖connect by,适配BI Publisher环境:
方案一:递归CTE(推荐,兼容性广)
递归公共表表达式是Oracle 11gR2及以上版本支持的标准语法,BI Publisher通常能很好兼容:
WITH date_range AS ( SELECT TO_DATE('2022-05-01', 'YYYY-MM-DD') AS read_date FROM dual UNION ALL SELECT read_date + 1 FROM date_range WHERE read_date + 1 <= TO_DATE('2022-05-05', 'YYYY-MM-DD') ) SELECT TO_CHAR(read_date, 'YYYY-MM-DD') AS read_date FROM date_range ORDER BY read_date;
方案二:XMLTABLE生成序列
利用XMLTABLE生成数字序列,再计算对应日期,写法更简洁:
固定天数版本
SELECT TO_CHAR(TO_DATE('2022-05-01', 'YYYY-MM-DD') + (num - 1), 'YYYY-MM-DD') AS read_date FROM XMLTABLE('1 to 5' COLUMNS num NUMBER PATH '.');
这里的5是结束日期与开始日期的间隔天数加1(2022-05-05 - 2022-05-01 + 1 = 5)
动态计算天数版本
如果需要自动计算日期范围的天数,可使用参数传递的方式:
SELECT TO_CHAR(start_date + (num - 1), 'YYYY-MM-DD') AS read_date FROM ( SELECT TO_DATE('2022-05-01', 'YYYY-MM-DD') AS start_date, TO_DATE('2022-05-05', 'YYYY-MM-DD') AS end_date FROM dual ), XMLTABLE('1 to xs:integer($end - $start + 1)' PASSING start_date AS start, end_date AS end COLUMNS num NUMBER PATH '.');
方案三:使用现有数字表
如果数据库中有现成的数字表(比如包含连续整数的numbers表),可以直接利用它:
SELECT TO_CHAR(TO_DATE('2022-05-01', 'YYYY-MM-DD') + (n - 1), 'YYYY-MM-DD') AS read_date FROM numbers WHERE n <= (TO_DATE('2022-05-05', 'YYYY-MM-DD') - TO_DATE('2022-05-01', 'YYYY-MM-DD') + 1);
内容的提问来源于stack exchange,提问作者dohan_rivas
相关产品推荐
相关产品推荐

