更新 sql 以更新 table 中每一行的最低层级数据

update sql to update lowest hierarchical data for each row in a table

我有一个table如下图

id previous_id latest_id
1 null null
2 1 null
3 2 null
4 null null
5 4 null
6 6 null

我想通过将 latest_id 列值设置为最低层次值来更新 table,如下所示:

id previous_id latest_id
1 null 3
2 1 3
3 2 3
4 null 6
5 4 6
6 5 6

我试过使用 connect by,但查询变得太复杂了,因为 start with 无法分配静态值,此更新适用于整个 table。

下面是我可以根据它的 id 为单个记录编写的内容,我如何将它概括为 table 中的所有记录?

UPDATE TABLENAME1 
   SET LATEST_ID = (SELECT MAX(ID)
                      FROM TABLENAME1
                     START WITH ID = 3
                   CONNECT BY PREVIOUS_ID = PRIOR ID );

您可以使用相关的分层查询和过滤器来获取叶行:

UPDATE table_name t
SET latest_id = (SELECT id
                 FROM   table_name h
                 WHERE  CONNECT_BY_ISLEAF = 1
                 START WITH h.id = t.id
                 CONNECT BY previous_id = PRIOR id);

其中,对于示例数据:

CREATE TABLE table_name (id, previous_id, latest_id) AS
SELECT 1, null, CAST(null AS NUMBER) FROM DUAL UNION ALL
SELECT 2, 1,    null FROM DUAL UNION ALL
SELECT 3, 2,    null FROM DUAL UNION ALL
SELECT 4, null, null FROM DUAL UNION ALL
SELECT 5, 4,    null FROM DUAL UNION ALL
SELECT 6, 5,    null FROM DUAL;

将 table 更新为:

ID PREVIOUS_ID LATEST_ID
1 null 3
2 1 3
3 2 3
4 null 6
5 4 6
6 5 6

db<>fiddle here

对于已接受的答案,我将添加这个替代方案,通过消除相关子查询,可能对大型数据集表现更好。

MERGE INTO table_name t
USING (  
  SELECT      CONNECT_BY_ROOT(id) root_id, id latest_id
  FROM        table_name
  WHERE       connect_by_isleaf = 1
  CONNECT BY  previous_id = prior id ) u
ON ( t.id = u.root_id )
WHEN MATCHED THEN UPDATE SET t.latest_id = u.latest_id;