ORACLE CONNECT BY LEVEL 产生重复行
Posted
技术标签:
【中文标题】ORACLE CONNECT BY LEVEL 产生重复行【英文标题】:ORACLE CONNECT BY LEVEL Producing Duplicate rows 【发布时间】:2019-11-07 14:49:36 【问题描述】:我正在尝试从包含多个注释的字符串中提取数据,这些注释附加到 varchar(4000) 列。我在查询中使用了正则表达式和函数的混合,以及使用 regexp_count 的 CONNECT BY LEVEL,因为我不知道是否会有一个音符或多个音符。当我返回结果时,我注意到有很多重复的行。我相信这纯粹是由于 CONNECT BY 而不是我之前必须使用的东西,所以我想我错过了一些东西。
这里是查询;
select
id,
substr(regexp_substr(VALUE,'^LOCKED BY USER: +(.*)',1,level,'m'),17) as LOCKUSER,
substr(regexp_substr(VALUE,'^LOCKED ENTITY: +(.*)',1,level,'m'),16) as LOCKED_ENTITY,
TO_DATE(LTRIM(regexp_substr(VALUE,'^LOCKED AT: ([[:digit:]]2/[[:digit:]]2/[[:digit:]]4\.?)',1,level,'m'),'LOCKED AT: '),'DD/MM/YYYY') as Dates_Locked,
substr(regexp_substr(VALUE,'^LOCK NOTES: +(.*)',1,level,'m'),13) as LOCK_NOTES,
'LOCK' as ACTION
from TABLE
where regexp_substr(VALUE,'^LOCK NOTES: +(.*)',1,level,'m') IS NOT NULL
AND TO_DATE(LTRIM(regexp_substr(VALUE,'LOCKED AT: ([[:digit:]]2/[[:digit:]]2/[[:digit:]]4\.?)',1,level,'m'),'LOCKED AT: '),'DD/MM/YYYY') >= (SYSDATE -365)
connect by level <= regexp_count(VALUE,CHR(10)||CHR(13));
如果我让它针对一个有 10K 记录的表运行,我将永远不会得到任何结果,我认为这是由于它返回的重复行的数量庞大。我有什么办法可以防止这种情况发生吗?
非常感谢
【问题讨论】:
确认我尝试 SELECT DISTINCT 没有成功 【参考方案1】:目前,您的CONNECT BY
仅限制层级,并没有提供任何将子行匹配到父行的条件。这意味着在具有多行的表中,每一行都是其他行的子行。这将产生一个庞大的结果集。
如果我理解正确,您正在尝试使用分层功能从每个单独的行中提取多个值。所以你真的希望每一行都是自己的父母和孩子。我建议尝试:
CONNECT BY id = PRIOR id
AND prior sys_guid() is not null
AND level <= regexp_count(VALUE,CHR(10)||CHR(13))
感谢@kfinity 指出需要 sys_guid() 来防止 CONNECT BY LOOP。
【讨论】:
谢谢戴夫,我刚刚试了一下,但不幸的是它抱怨... ORA-01436:用户数据 01436 中的 CONNECT BY 循环。00000 -“用户数据中的 CONNECT BY 循环”*原因:*行动: 如果你得到了 ORA-01436,你可能还需要添加and prior sys_guid() is not null
完美!就像我发布它一样,你抢先了我的问题!我刚刚添加了“并且之前的 sys_guid() 不为空”,现在效果很好!感谢您的帮助!以上是关于ORACLE CONNECT BY LEVEL 产生重复行的主要内容,如果未能解决你的问题,请参考以下文章
oracle connect by 和 start with 的用法