oracle中的sql递归查询,直到层次结构中的父级满足条件为止?

anauzrmj  于 2021-07-29  发布在  Java
关注(0)|答案(2)|浏览(387)

我有一张如下的table:

ID  PARENT_ID  VALUE_ID
1   NULL       100
2   1          NULL
3   2          200
4   3          NULL 
5   1          300
6   2          NULL
7   6          400
8   7          500

我希望能够获取每个id及其对应的值,如果一行的值为null,它将“继承”层次结构中第一个父级的值,该父级的值为notnull。这就是查询结果:

ID  VALUE_ID
1   100
2   100      // -> inherits the value from PARENT_ID = 1;  
3   200
4   200      // -> inherits the value from PARENT_ID = 3;
5   300
6   100      // -> inherits the value from ID = 1, because the PARENT_ID = 2 also has VALUE_ID as NULL, so it goes deeper in the hierarchy;
7   400    
8   500

只有一个递归或层次查询可以完成这样的事情吗?或者不需要程序就可以完成?使用cte,还是connect by子句?

kr98yfug

kr98yfug1#

您可以为此使用递归cte:

with cte(id, value_id, parent_value_id) as (
      select id, value_id, value_id as parent_value_id
      from t
      where value_id is not null
      union all
      select t.id, t.value_id, cte.parent_value_id
      from cte join
           t
           on t.parent_id = cte.id
      where t.value_id is null
     )
select *
from cte
order by id;

这是一把小提琴。

mf98qq94

mf98qq942#

可以使用相关的层次查询和 CONNECT_BY_ISLEAF 只返回一行:

SELECT id,
       parent_id,
       ( SELECT value_id
         FROM   table_name r
         WHERE  connect_by_isleaf = 1
         START WITH r.id = t.id
         CONNECT BY PRIOR parent_id = id
         AND PRIOR value_id IS NULL
       ) AS value_id
FROM   table_name t

因此,对于您的测试数据:

CREATE TABLE table_name ( ID, PARENT_ID, VALUE_ID ) AS
SELECT 1, NULL, 100  FROM DUAL UNION ALL
SELECT 2, 1,    NULL FROM DUAL UNION ALL
SELECT 3, 2,    200  FROM DUAL UNION ALL
SELECT 4, 3,    NULL FROM DUAL UNION ALL
SELECT 5, 1,    300  FROM DUAL UNION ALL
SELECT 6, 2,    NULL FROM DUAL UNION ALL
SELECT 7, 6,    400  FROM DUAL UNION ALL
SELECT 8, 7,    500  FROM DUAL

这将输出:

ID | PARENT_ID | VALUE_ID
-: | --------: | -------:
 1 |      null |      100
 2 |         1 |      100
 3 |         2 |      200
 4 |         3 |      200
 5 |         1 |      300
 6 |         2 |      100
 7 |         6 |      400
 8 |         7 |      500

db<>在这里摆弄

相关问题