2016-07-08 2 views
2
이 테이블을 감안할 때

...SQL Server 재귀 CTE -이 동작이 필요한 이유는 무엇입니까?

CREATE TABLE tblEmployees (
    EmployeeID SMALLINT, 
    ReportsTo SMALLINT, 
    IsBigBoss BIT); 

CREATE TABLE tblTargetEmployees (
    EmployeeID SMALLINT); 

INSERT INTO tblEmployees VALUES 
(1,NULL,NULL), 
(2,1,1), 
(3,1,1), 
(4,1,1), 
(5,1,1), 
(6,2,0), 
(7,6,0), 
(8,6,0), 
(9,3,0), 
(10,4,0), 
(11,10,0), 
(12,10,0), 
(13,5,0), 
(14,2,0), 
(15,10,0); 

INSERT INTO tblTargetEmployees VALUES 
(8), 
(9), 
(10), 
(11), 
(12), 
(14); 

그리고이 쿼리 ...

WITH cte AS (
    SELECT e.EmployeeID, BigBossID=e.EmployeeID, e.ReportsTo 
     FROM tblEmployees e 
     WHERE e.IsBigBoss=1 

    UNION all 

    SELECT e.EmployeeID, cte.BigBossID, e.ReportsTo 
     FROM tblEmployees e 
      JOIN cte ON e.ReportsTo=cte.EmployeeID 
) 

SELECT * 
    FROM cte 
    WHERE EXISTS (SELECT * FROM tblTargetEmployees te WHERE te.EmployeeID=cte.EmployeeID) 
    ORDER by EmployeeID 

는 내가 예상 한 결과를 얻을 수 있습니다. 목표 테이블에있는 6 명의 직원 모두가 반환됩니다. 그러나 대신 필터를 cte로 옮기면 직원 (# 8)이 삭제됩니다. 나는 CTE에 필터를 이동할 때 내 여분의 "빅 보스"행을 건너 왜

WITH cte AS (
    SELECT e.EmployeeID, BigBossID=e.EmployeeID, e.ReportsTo 
     FROM tblEmployees e 
     WHERE e.IsBigBoss=1 

    UNION all 

    SELECT e.EmployeeID, cte.BigBossID, e.ReportsTo 
     FROM tblEmployees e 
      JOIN cte ON e.ReportsTo=cte.EmployeeID 
     WHERE EXISTS (SELECT * FROM tblTargetEmployees te WHERE te.EmployeeID=e.EmployeeID) 
) 

SELECT * 
    FROM cte 
    ORDER by EmployeeID 

는 지금, 나는 이해하지만 나는 직원 ID (8)가 필터링됩니다 왜 주위에 내 머리를 포장 힘든 시간을 보내고 있습니다.

이 동작에 대한 내 간단한 마음을 감싸는 데 도움이되는 모든 도움을 주시면 감사하겠습니다.

+0

원하는 볼 수 있습니다 ..... 찾을 수 기다리고 있습니다 필터링 된 직원? – usr

+0

D' oh! 그게 전부 야. 고맙습니다!! –

답변

2

EmployeeId 6은 tblTargetEmployees에 존재하지 않으므로 재귀가 발생하고 직원 ID 6을 추가하기 시작하면 tblTargetEmployees 테이블에 있는지 확인합니다. 재귀의 라인이 경우 중지하고 8

그래서

  • 6가 직접 보스

    • 2 bigboss에게하고 앵커 테이블에 표시되는 데이터를 사용하는 직원 ID에 도달하지 있도록하지 않습니다 존재하지 않기 때문에 그 후에 재귀를 호출하지 않습니다.
    • 8
    • 아마 # 8의 자식이었다
    CTE에 당신의 WHERE 문 outsde 이동

    당신은 결과가 당신이

    ;WITH cte AS (
        SELECT e.EmployeeID, BigBossID=e.EmployeeID, e.ReportsTo 
         FROM tblEmployees e 
         WHERE e.IsBigBoss=1 
    
        UNION all 
    
        SELECT e.EmployeeID, cte.BigBossID, e.ReportsTo 
         FROM tblEmployees e 
          JOIN cte ON e.ReportsTo=cte.EmployeeID 
    ) 
    
    SELECT * 
        FROM cte e 
        WHERE EXISTS (SELECT * FROM tblTargetEmployees te WHERE te.EmployeeID=e.EmployeeID) 
        ORDER by EmployeeID