2016-07-12 2 views
0

이 테이블 갖는SQL의 인접리스트에 주어진 루트의 모든 노드를 삭제하는 방법

enter image description here

내가 쿼리 ID = 1 을 전송하여, 루트 노드를 삭제할 내가 모든 것을 할을 이 id의 하위 노드도 삭제됩니다.

어떻게하면됩니까?

+2

그래서, 당신은 'ID = 1'을 삭제하는 경우 세 개의 레코드를 삭제해야합니까? 테이블에서 더 많은 레코드를 보여줄 수 있습니까? – gotqn

+0

@gotqn 네, 맞습니다. 더 이상은 없다. 그것은 테이블 예제이다. 당신은 ID 4와 같은 더 많은 레코드를 가질 수 있습니다. 이름 2 소유자 2 부모 NULL 등. – eyalewin

답변

2

이 재귀 공통 테이블 표현식을 사용하여 수행 할 수 있습니다.

하는 하나 개의 노드의 모든 아이들이 사용할 수 얻으려면 :

with tree as (
    select id, parent 
    from eyalewin 
    where id = 1 
    union all 
    select c.id, c.parent 
    from eyalewin c 
    join tree p on p.id = c.parent 
) 
select * 
from tree; 

이는 그들 모두를 삭제하는 데 사용할 수 있습니다

with tree as (
    select id, parent 
    from eyalewin 
    where id = 1 
    union all 
    select c.id, c.parent 
    from eyalewin c 
    join tree p on p.id = c.parent 
) 
delete from eyalewin 
where id in (select id 
      from tree); 
2

의는 다음과 같은 데이터가 있다고 가정 해 봅시다 :

enter image description here

하고 (이 경우 2.1.3에서만) 레코드 2.1과 그의 후손 모두 삭제합니다. 우리는 hierarchy id 유형에 기록을 변환 기본적으로

WITH DataSource ([ID], [HierarchyLevel]) AS 
(
    SELECT [ID] 
      ,CAST(REPLACE('/' + [Name] + '/', '.', '/') AS HIERARCHYID) 
    FROM @DataSource 
) 
SELECT [ID] 
     ,[HierarchyLevel].ToString() 
FROM DataSource 
WHERE [HierarchyLevel].IsDescendantOf('/2/1/') = 1; 

enter image description here

모든 childs의 얻을 IsDescendantOf 기능에 빌드 - 더를 사용 : 당신은 삭제해야 할 IDs 얻기 위해 다음과 같은 코드를 사용할 수 있습니다 노드

이 전체 작업 예 :

DECLARE @DataSource TABLE 
(
    [ID] TINYINT 
    ,[Name] VARCHAR(12) 
    ,[Owner] VARCHAR(12) 
    ,[Parent] INT 
); 

INSERT INTO @DataSource ([ID], [Name], [Owner], [Parent]) 
VALUES (1, '1', '1', NULL) 
     ,(2, '1.1', '1.1', 1) 
     ,(3, '1.1.1', '1.1.1', 2) 
     ,(4, '2', '2.1', NULL) 
     ,(5, '2.1', '2.1', 4) 
     ,(6, '2.2', '2.2', 4) 
     ,(7, '2.1.3', '2.1.3', 5); 


WITH DataSource ([ID], [HierarchyLevel]) AS 
(
    SELECT [ID] 
      ,CAST(REPLACE('/' + [Name] + '/', '.', '/') AS HIERARCHYID) 
    FROM @DataSource 
) 
DELETE @DataSource 
FROM @DataSource DS 
INNER JOIN DataSource DS1 
    ON DS.[ID] = DS1.[ID] 
WHERE [HierarchyLevel].IsDescendantOf('/2/1/') = 1; 

SELECT * 
FROM @DataSource; 
관련 문제