如何解决Oracle查询起始日起5周日期时出现重复数据的问题?
解决Oracle递归查询生成日期时重复行的问题
需求是查询COMMUNITY分支从2023-07-03起5周(共35天)的所有日期,但你写的递归查询返回了大量重复数据,问题出在递归关联条件缺失。
问题原因
原SQL的connect by没有指定父行与子行的关联规则,当表中存在多行数据时,递归过程会对每一行都进行层级展开,不同行的递归逻辑互相交叉,最终生成大量重复的日期记录。
解决方案
这里提供几种可行的写法,都能避免重复行:
方法1:先过滤目标行再生成日期
通过子查询先取出COMMUNITY分支的单一行数据,再基于这一行做递归,彻底避免其他行的干扰:
SELECT BR_START + LEVEL - 1 AS DT FROM ( SELECT BR_START, BR_COURSE_LN FROM T4S_BRANCH_DATA WHERE BR_NAME = 'COMMUNITY' ) CONNECT BY LEVEL <= BR_COURSE_LN * 7;
方法2:给connect by加关联限制
如果不想用子查询,可以在connect by里添加PRIOR条件锁定当前行,同时用SYS_GUID()防止递归循环:
SELECT BR_START + LEVEL - 1 AS DT FROM T4S_BRANCH_DATA WHERE BR_NAME = 'COMMUNITY' CONNECT BY LEVEL <= BR_COURSE_LN * 7 AND PRIOR BR_NAME = BR_NAME AND PRIOR SYS_GUID() IS NOT NULL;
方法3:直接基于固定日期范围生成
如果已知起始和结束日期,也可以直接用WITH子句定义范围,再生成日期,逻辑更直观:
WITH date_range AS ( SELECT TO_DATE('2023-07-03', 'YYYY-MM-DD') AS start_date, TO_DATE('2023-07-03', 'YYYY-MM-DD') + 5*7 - 1 AS end_date FROM DUAL ) SELECT start_date + LEVEL - 1 AS DT FROM date_range CONNECT BY LEVEL <= end_date - start_date + 1;
验证结果
以上三种写法都会返回从2023-07-03到2023-08-06的35条唯一日期记录,不会有重复。
内容的提问来源于stack exchange,提问作者user20834985
相关产品推荐
相关产品推荐

