在Oracle中进行递归连接的最佳方法是什么?假设我有一个如下架构:
node:
id: number
parent_id: number
name: string
我如何与其所有父节点一起加入子节点?
我尝试过以下但是失败了:
SELECT c.* from node LEFT JOIN(
SELECT * FROM node c
START WITH id = c.id
CONNECT BY PRIOR id = parent_id
) ON 1 = 1
抱怨START WITH id = c.id部分。
答案 0 :(得分:1)
基本上你需要一个从哪里开始的起点,所以会有一个id没有parent_id
及其null
,所以我在这里解释id 1没有parent_id。
create table node (id number,parent_id number,name varchar2(200));
insert into node values(1,null,'king');
insert into node values(2,1,'gaurav');
insert into node values(3,1,'rohan');
insert into node values(4,2,'anshoo');
insert into node values(5,4,'ajay');
select id,parent_id,name from node
start with parent_id is null
connect by prior id= parent_id;
sqlfiddle link
答案 1 :(得分:1)
根据您在问题中提供的信息,很难说出您真正要实现的目标,但在我看来,您希望为每个ID
显示子树(主树从ID = 1,让我们按顺序排序,然后从ID = 2开始子树,依此类推。)
以下是一个例子:
with Tb_Table (id, parent_id, name) as(
select 1, 1, 'Child_1' from dual union all
select 2, 1, 'Child_2' from dual union all
select 3, 3, 'Child_3' from dual
),
rec_data (id, parent_id, name, lv) as(
select id
, parent_id
, name
, 0 lv
from Tb_Table
where id = id
union all
select tt.id
, tt.parent_id
, tt.name
, lv + 1
from rec_data rt
join tb_table tt
on (rt.id = tt.parent_id)
)
search depth first by id set ord
cycle id set is_cycle to 'Y' default 'N'
select id
, parent_id
, concat(lpad(' ', lv*3,' '), name) name
from rec_data
结果:
Id Parent_Id Name
-----------------------
1 1 Child_1
1 1 Child_1
2 1 Child_2
2 1 Child_2
3 3 Child_3
3 3 Child_3
答案 2 :(得分:0)
c
位于联接中的某个位置,无法在括号外到达,但我认为您应该一步一步地学习如何使用connect by
。老实说,这个链接帮助我学习和理解它:http://www.adp-gmbh.ch/ora/sql/connect_by.html
答案 3 :(得分:-4)
(看起来你正在使用)支持递归查询。以下面的示例为用户分配到许多位置。每个位置都可以有父位置。此查询返回@userID分配给的所有位置和子位置。
ALTER FUNCTION [dbo].[tvf_UserLocations_Recursive]
(
@UserID uniqueidentifier
)
RETURNS TABLE
AS
RETURN
(
WITH recusrive (LocationID)
AS (
--anchor
SELECT LocationID
FROM LocationUser lu
WHERE lu.Aspnet_Userid = @userID
UNION ALL
-- Recursive member definition
SELECT child.LocationID
FROM recusrive parent
INNER JOIN Location child ON (parent.LocationID = child.LocationParentID)
)
SELECT *
FROM recusrive
)