进行递归连接的最佳方法是什么?

时间:2012-09-28 20:50:29

标签: sql oracle

在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部分。

4 个答案:

答案 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 

Demo

答案 2 :(得分:0)

c位于联接中的某个位置,无法在括号外到达,但我认为您应该一步一步地学习如何使用connect by。老实说,这个链接帮助我学习和理解它:http://www.adp-gmbh.ch/ora/sql/connect_by.html

答案 3 :(得分:-4)

SQL Server中的

(看起来你正在使用)支持递归查询。以下面的示例为用户分配到许多位置。每个位置都可以有父位置。此查询返回@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
)