2015-01-16 2 views
-3

아래 두 테이블이 정의되어 있습니다. 이름은 부모 - 자식 관계로 정렬됩니다. [Level]은 최상위 레벨 (루트 : 레벨 = 0, 루트의 첫 번째 하위 : 레벨 = 1)을 나타내는 [ID], [이름] 및 [레벨]을 포함하는 이름의 중첩 된 트리 목록을 표시하는 방법 등 ...).관계를 가져 오기위한 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 서버를 사용하고 2008

+0

하는 ** 데이터베이스 ** 예상 출력을 사용하여 질문을 사용하고 편집하고 있습니다. –

+0

ms sql serv를 사용하고 있습니다. 어 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 

참고 : Names 테이블 엔트리를 가지고 있지 않기 때문에 관계 테이블의 첫 번째 행 (예) INSERT [RELATIONSHIPS] VALUES (1,0)에서 당신은 자식 열에 0을 삽입 할 수 없습니다.

는 루트 다음 다음 INSERT [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

처럼 NULL 대신 0를 사용할 수있는 경우, 나는이 다정하고 간단한 방법이라고 생각

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 
관련 문제