首页 > 解决方案 > 在oracle sql中循环

问题描述

我想将列 ID_last 添加到下方左侧的表格中。示例表由 6 行和 8 行的两个序列组成。我需要处理许多序列和每个序列的未知/无限行数/每个序列的循环。当 ID 不在 ID_new 中时序列开始,当 ID_new 不在 ID 中时序列停止。我想知道序列中所有 ID 的最后一个 ID_new(如右表所示)。

如何使用 SQL (oracle) 执行此操作?

非常感谢您的帮助!

见表图片:)

标签: sqloracleloopsplsql

解决方案


由于可以使用此查询确定任何序列中的最后一个 ID:

select id_new from YourData yd
 where not exists (select 1 from YourData yd2
                    where yd2.id = yd.id_new);

我们可以将问题视为以标识的 ID_Last 值为根的分层查询,将根 ID 作为 ID_Last 返回:

select id
     , id_new
     , CONNECT_BY_ROOT id_new ID_Last
  from YourData yd
  connect by NOCYCLE id_new = prior id
 start with not exists (select 1 from YourData yd2
                         where yd2.id = yd.id_new)

或者,这可以写为递归查询,使用上面的第一个查询(带有附加列)作为锚查询。为了避免循环,我们必须添加一个列来跟踪已经访问过的节点,并在查询的递归部分检查它:

With Recur(id, id_new, id_last, nodes) as (
  select id
       , id_new
       , id_new
       , ':'||id||':'
    from YourData yd1
   where not exists (select 1 from YourData yd2
                      where yd2.id = yd1.id_new)
   union all
  select yd.id
       , yd.id_new
       , r.id_last
       , r.nodes||yd.id||':'
    from YourData yd
    join Recur r
      on r.id = yd.id_new
     and r.nodes not like '%:'||yd.id||':%' -- Avoid cycles
)
select id, id_new, id_last
  from Recur
 order by id_last
     , nodes desc;

推荐阅读