1

在 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

4 回答 4

1

基本上你需要一个从哪里开始的起点,所以会有一个没有的 idparent_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 链接

于 2012-09-28T21:19:54.553 回答
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 

演示

于 2012-09-29T19:08:42.537 回答
0

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

于 2012-09-28T21:18:51.990 回答
-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
)
于 2012-09-28T20:55:30.847 回答