Oracle PostgreSQL和过滤递归查询
在Oracle中,可以使用子句Oracle PostgreSQL和过滤递归查询,oracle,postgresql,filtering,recursive-query,Oracle,Postgresql,Filtering,Recursive Query,在Oracle中,可以使用子句connectby和START with查询树 例如: SELECT RPAD (' ', (LEVEL - 1) * 4) || node_name AS node, LEVEL FROM hierarchy START WITH NVL (pig_ear_id, 0) = 0 CONNECT BY PRIOR id = pig_ear_id; 可以简单地筛选查询结果,以显示筛选谓词接受的或位于根路径上的唯一节点: SELECT RPAD (' ',
connectby
和START with
查询树
例如:
SELECT RPAD (' ', (LEVEL - 1) * 4) || node_name AS node, LEVEL
FROM hierarchy
START WITH NVL (pig_ear_id, 0) = 0
CONNECT BY PRIOR id = pig_ear_id;
可以简单地筛选查询结果,以显示筛选谓词接受的或位于根路径上的唯一节点:
SELECT RPAD (' ', (LEVEL - 1) * 4) || node_name AS node, LEVEL
FROM hierarchy
START WITH NVL (pig_ear_id, 0) = 0
CONNECT BY PRIOR id = pig_ear_id AND id IN (
SELECT id
FROM hierarchy
START WITH node_name = 'some-pattern'
CONNECT BY PRIOR pig_ear_id = id
);
PostgreSQL中类似的select将使用带有递归…的子句构建。据我所知,一个with query不能包含在另一个with query中,以获得Oracle允许的相同过滤结果
如何重写PostgreSQL中的第二个select?。如果有一个with查询正在调用某个函数,而该函数又有一个with查询,
然后它允许我们,并且不会引发任何错误…这样我们仍然能够嵌套查询
因此,我通常使用with子句创建一个查询。请参见下面的第一个查询。
它有in子句,其中select查询选择函数返回的记录(my_函数)。
该函数具有另一个层次结构和查询
我也不知道你想从查询中返回什么。所以根据需要更改查询。这只是实现所需结构的方法
以下是sql server的语法。请对任何其他数据库进行适当更改
with alias_list
(
pig_ear_id,
node_name,
id
) as (
select pig_ear_id, node_name, id
from hierarchy
where pig_ear_id = ?
union all
select b.pig_ear_id, node_name, id
from alias_list a, hierarchy b
where a.pig_ear_id = b.id
and id in (select id from my_function('some-pattern')))
select * from alias_list;
==============================================================
create function my_function(@node_name varchar(40))
returns @temptable table
(
id varchar(40)
)
as
begin
with alias_list
(
pig_ear_id,
node_name,
id
) as (
select pig_ear_id, node_name, id
from hierarchy
where node_name = ?
union all
select b.pig_ear_id, node_name, id
from alias_list a, hierarchy b
where a.id = b.pig_ear_id)
insert into @temptable select * from alias_list;
return
end
================================================================
create function my_function(@node_name varchar(40))
returns @temptable table
(
id varchar(40)
)
as
begin
with alias_list
(
pig_ear_id,
node_name,
id
) as (
select pig_ear_id, node_name, id
from hierarchy
where node_name = ?
union all
select b.pig_ear_id, node_name, id
from alias_list a, hierarchy b
where a.id = b.pig_ear_id)
insert into @temptable select * from alias_list;
return
end
据我所知,一个带查询不能包含在另一个带查询中
当然,你可以一个接一个地写:
with recursive valid_nodes as (
-- this is the inner "CONNECT BY" query from your example
select id
from hierarchy
where node_name = 'some-pattern'
union all
select c.id
from hierarchy c
join valid_nodes p on c.id = p.pig_ear_id
), final_tree as (
-- this is outer query from your example
select node_name as node, 1 as level
from hierarchy
where NVL (pig_ear_id, 0) = 0
union all
select c.node_name, p.level + 1
from hierarchy c
join final_tree p on p.id = c.pig_ear_id
where id in (select id from valid_nodes) -- and here we re-use the previous CTE
)
select rpad(node, level - 1)||node, level
from final_tree;
注意,recursive
关键字只需在开头说明。不管您有多少递归CTE(但如果您使用CTE链,则需要在CTE链中至少有一个)。无需函数。CTE(又名“带查询”)可以嵌套(实际上是链式的)@a_horse_,并没有名称,同意吗