2015-01-16 92 views
-3

下面定義了兩個表。姓名以父母 - 子女關係排列。如何顯示名稱的嵌套(樹)列表,包括[Id],[Name]和[Level],其中[Level]表示頂層的嵌套層次(Root:Level = 0; Root的第一個子層:Level = 1 ;等等......)。用於獲取關係的sql查詢

CREATE TABLE [Names] 
(
[Id] INT PRIMARY KEY, 
[Name] VARCHAR(100) 
) 

CREATE TABLE [Relationships] 
(
[Parent] [int] REFERENCES [Names]([Id]), 
[Child] [int] REFERENCES [Names]([Id]) 
) 



INSERT [NAMES] VALUES (1,'FRANK') 
INSERT [NAMES] VALUES (2,'JO') 
INSERT [NAMES] VALUES (3,'MARY') 
INSERT [NAMES] VALUES (4,'PETER') 
INSERT [NAMES] VALUES (5,'MAY') 

INSERT [RELATIONSHIPS] VALUES (1,0) 
INSERT [RELATIONSHIPS] VALUES (2,1) 
INSERT [RELATIONSHIPS] VALUES (3,2) 
INSERT [RELATIONSHIPS] VALUES (4,1) 
INSERT [RELATIONSHIPS] VALUES (5,2) 

我使用的MS SQL Server 2008

+0

這**數據庫**您正在使用和編輯預期的輸出問題 –

+0

我正在使用MS SQL SERVER呃2008年 – Kumar1986

回答

0

公共表表達式允許你做這樣的事情遞歸調用。搜索那個。它會像這樣:

with cte as (
    select *, 1 as lvl 
    from relationships as a 
    join names as b ... 
    union 
    select *, lvl + 1 
    from .... 
) 
select * from cte; 

我可能沒有完全正確,但搜索cte遞歸將有所幫助。

0

使用Recursive CTE來做到這一點。

;WITH cte 
    AS (SELECT NAME, 
       Parent, 
       Child, 
       0 AS level 
     FROM [Names] N 
       JOIN Relationships r 
        ON r.Parent = n.Id 
     WHERE Child IS NULL 
     UNION ALL 
     SELECT b.NAME, 
       b.Parent, 
       b.Child, 
       level + 1 
     FROM cte a 
       JOIN (SELECT NAME, 
          Parent, 
          Child 
         FROM [Names] N 
          JOIN Relationships r 
           ON r.Parent = n.Id) b 
        ON a.Parent = b.Child) 
SELECT * FROM cte 

注:在關係表中第一行(IE)INSERT [RELATIONSHIPS] VALUES (1,0)你不能在孩子柱插入0因爲Names表中沒有這樣的條目。

如果它是根,然後那麼你可以使用NULL,而不是像0INSERT [RELATIONSHIPS] VALUES (1,null)

0
CREATE TABLE [Names] 
(
    [Id] INT PRIMARY KEY, 
    [Name] VARCHAR(100) 
) 

CREATE TABLE [Relationships] 
( 
    [Child] [int] REFERENCES [Names]([Id]), 
    [Parent] [int] REFERENCES [Names]([Id]) 
) 

INSERT [NAMES] VALUES (1,'FRANK') 
INSERT [NAMES] VALUES (2,'JO') 
INSERT [NAMES] VALUES (3,'MARY') 
INSERT [NAMES] VALUES (4,'PETER') 
INSERT [NAMES] VALUES (5,'MAY') 

INSERT [RELATIONSHIPS] VALUES (1,Null) 
INSERT [RELATIONSHIPS] VALUES (2,1) 
INSERT [RELATIONSHIPS] VALUES (3,2) 
INSERT [RELATIONSHIPS] VALUES (4,1) 
INSERT [RELATIONSHIPS] VALUES (5,4) 

--first have a look at INSERT [RELATIONSHIPS] VALUES (1,0), you are 
    --saying 0 is the child of 1. I think you need to swap the column 
    --names? - this solution assumes you meant parent to be child 
    --and visa-versa - i.e. I swapped them above 
--second, do you need the relationships table? cant you just have a 
    --reports_to column in the names table? 
--third, you cant have a value of 0 in either column of your relationships 
    --table because of the FK constraint to names - no name exists 
    --with id = 0, insert NULL instead 
--fourth, I changed May's manager so that it was clear that lvl & manager werent related 

;with 
cte as 
    (select id, name, isnull(parent,0) as manager 
    from Names n 
     left join Relationships r 
      on r.child = n.id), 
r_cte as 
    (select 0 as lvl, id, name, manager 
    from cte 
    where manager = 0 
    union all 
    select r.lvl + 1, c.id, c.Name, c.manager 
    from cte c 
     inner join r_cte r 
      on c.manager = r.id 
    ) 
select * from r_cte 
1

我認爲這是甜蜜的,簡單的方法

SELECT child AS ID , N.Name , ISNULL(R.Parent, 0) AS Lavel 
FROM Relationships R ,NAMES N 
WHERE R.Child = N.Id ORDER BY parent,child 

ID Name Level 
1 FRANK 0 
2 JO  1 
4 PETER 1 
3 MARY 2 
5 MAY  2