更新 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;
我有一个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;