是否可以递归查询?

Is a recursive query possible?

一个 Oracle SQL 问题,对我来说似乎很简单,但我就是做不到(没有手动进行几个连续的查询)...我想使用 SQL "递归”方法或任何其他可以避免我手动使用“n”次相同查询的方法。

这是我的数据的一个非常简单的例子:

row ID Value Result
1 135 AAA AAA
2 246 BBB BBB
3 357 135 AAA
4 468 357 AAA
5 578 EEE EEE

如果一个值引用了一个ID,那么我们需要获取该ID的值。如果一个 ID 的值是另一个 ID,那么你必须继续寻找一个“真”值。如果这个值不是ID,那么我们可以直接取。

“结果”列给出了预期的结果:

对于第 3 行,您必须查找 ID 135 的值。

对于第 4 行,您必须获取 ID 357 的值,该值对应于 ID 135 的值。

在这里,我不想做的事情:

with my_data as(
    select '135' as id, 'AAA' as value from dual union all
    select '246', 'BBB' from dual union all
    select '357', '135' from dual union all
    select '468', '357' from dual union all
    select '578', 'EEE' from dual
)
,step as(
    select d1.*
          ,nvl((select d2.value from my_data d2 where d1.value=d2.id),d1.value) as step_1
    from my_data d1
)
-- steps to do again and again...
select step.*
      ,nvl((select my_data.value from my_data where step.step_1=my_data.id),step.step_1) as step_n
from step
order by 1
;

感谢您的帮助。


除了Carlos S anwser:

它完全符合我在“非常简化”的示例中的要求。然而,对于真实数据的一个子集,有一些问题(数据有点太多)。另一方面,如果我删除引用 ID 的结果,它会给出我想要的结果。我找不到问题。

注意:如我最初的示例所示,ID 始终以数字开头,“真实”值始终以字母开头。所以正则表达式策略是“好的”。

这是一个真实的例子:

with my_data as(
    select '116554226_2' as id, '116554226_1' as value from dual union all
    select '119675285_2' as id, '119675285_1' as value from dual union all
    select '119675285_3' as id, '119675285_2' as value from dual union all
    select '13656777_1' as id, '119675471_1' as value from dual union all
    select '13656777_5001' as id, '119675471_1' as value from dual union all
    select '13656777_2' as id, '13656777_1' as value from dual union all
    select '13656155_1' as id, '13657581_1' as value from dual union all
    select '13657581_2' as id, '13657581_1' as value from dual union all
    select '13657015_1' as id, '13657759_1' as value from dual union all
    select '13657759_2' as id, '13657759_1' as value from dual union all
    select '116554226_1' as id, '471502681_1' as value from dual union all
    select '462721769_1' as id, 'O7X5J' as value from dual union all
    select '471502681_1' as id, 'T3L8L' as value from dual union all
    select '119675471_1' as id, 'T8Q0G' as value from dual union all
    select '119675471_5001' as id, 'T8Q0G' as value from dual union all
    select '116555133_1' as id, 'T9J2Q' as value from dual union all
    select '13657581_1' as id, 'U5H5Z' as value from dual union all
    select '119674049_1' as id, 'Y5G7V' as value from dual union all
    select '13657759_1' as id, 'Z0Y9C' as value from dual union all
    select '119675285_1' as id, 'Z7E0D' as value from dual
)
SELECT my_data.*, CONNECT_BY_ROOT value result
FROM   my_data
CONNECT BY PRIOR id = value 
START WITH REGEXP_LIKE(value,'[^0-9]')
;

盒装数据不要,否则下面一切正常。

我认为这个查询可能对您有帮助:

with my_data as(
  select '135' as id, 'AAA' as value from dual union all
  select '246', 'BBB' from dual union all
  select '357', '135' from dual union all
  select '468', '357' from dual union all
  select '578', 'EEE' from dual
)
SELECT rownum, id, value, CONNECT_BY_ROOT value result
FROM   my_data
CONNECT BY PRIOR id = value 
START WITH REGEXP_LIKE(value,'[^0-9]')
ROWNUM ID VALUE RESULT
1 135 AAA AAA
2 357 135 AAA
3 468 357 AAA
4 246 BBB BBB
5 578 EEE EEE