2012-09-28 101 views
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 

它抱怨使用id = c.id部分開始。

+0

什麼是 「C」?你沒有定義它。另外,你可以給出一個示例表和預期的查詢結果嗎? –

+0

對不起,意思是把c放在節點後面,仍然有問題。 – moger777

+2

你到底想要做什麼?你能給我們一些樣本數據和預期的產出嗎? –

回答

-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 
) 
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

這真的很難說什麼你真的想基於你在你提供的有關資料來實現的,但在我看來,要顯示每個子樹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