2008-08-29 2 views
1

아래 코드에서 SQL Server 2005의 재귀 CTE (Common Table Expression)를 사용하여 기본 계층 구조의 최상위 수준 부모를 찾으려고합니다. 이 계층의 규칙은 모든 CustID에 ParentID가 있고 CustID에 부모가없는 경우 ParentID = CustID이며 최상위 레벨이라는 규칙이 있습니다.재귀 CTE에서 마지막 레코드를 어떻게 생성합니까?

DECLARE @LookupID int 

--Our test value 
SET @LookupID = 1 

WITH cteLevelOne (ParentID, CustID) AS 
(
     SELECT a.ParentID, a.CustID 
     FROM  tblCustomer AS a 
     WHERE a.CustID = @LookupID 
    UNION ALL 
     SELECT a.ParentID, a.CustID 
     FROM  tblCustomer AS a 
     INNER JOIN cteLevelOne AS c ON a.CustID = c.ParentID 
     WHERE c.CustID <> a.CustomerID 
) 

그래서 tblCustomer은 다음과 같습니다 경우 :

ParentID CustID 
5   5 
1   8 
5   4 
4   1 

나는 위의 코드에서 얻을 결과입니다 : 내가 원하는 것은 그 결과의 맨 마지막 줄이

ParentID CustID 
4   1 
5   4 
5   5 

:

ParentID CustID 
5   5 

o CTE (최상위 CustID가 될 것입니다)에서 생성 된 마지막 레코드 만 반환합니까?

이 테이블에는 무관 한 CustID 계층 구조가 여러 개 있으므로 SELECT * FROM tblCustomer WHERE ParentID = CustID를 수행 할 수 없습니다. ID 번호가 계층 구조의 위치와 관련이 없으므로 ParentID 또는 CustID로 주문할 수 없습니다.

답변

2

가장 높은 재귀 수준을 원한다면 이렇게 할 수 없습니까? 그렇다면 실제로 CTE를 쿼리 할 때 max (Depth)로 행을 찾으십니까? 그래서 같이 :

DECLARE @LookupID int 

--Our test value 
SET @LookupID = 1; 

WITH cteLevelOne (ParentID, CustID, Depth) AS 
(
     SELECT a.ParentID, a.CustID, 1 
     FROM  tblCustomer AS a 
     WHERE a.CustID = @LookupID 
    UNION ALL 
     SELECT a.ParentID, a.CustID, c.Depth + 1 
     FROM  tblCustomer AS a 
     INNER JOIN cteLevelOne AS c ON a.CustID = c.ParentID 
     WHERE c.CustID <> a.CustID 
) 
select * from CTELevelone where Depth = (select max(Depth) from CTELevelone) 

나, 트레버 알 무엇 적응이 동일한 CTE와 함께 사용될 수있다 :

select top 1 * from CTELevelone order by Depth desc 

내가 CustomerID를 당신이 경우에 의한 주문 원하는 것을 반드시 생각하지 않습니다 당신이 설명했지만, 나는 그 질문에 대해서도 완벽하게 명확하지 않았습니다.

1

내가 충분히 문제를 이해하지만, 당신이 시도 할 수 그것에 & 슬래시를 해킹하지 확신 다음 CustID이 예에서와 같이 위해도 아닌 것으로 가정

SELECT TOP 1 FROM cteLevelOne ORDER BY CustID DESC 

GUID와 같은 것.

0

먼저 부모 자식이 동일하면 cte가 완료되지 않습니다. 재귀 적 CTE이므로 종료되어야합니다. 학부모와 고객 ID가 동일하면 루프가 종료되지 않습니다.

메시지 레벨 530, 수준 16, 상태 1, 줄 15 문을 종료했습니다. 명령문 완료 전에 최대 재귀 100이 모두 소모되었습니다.

관련 문제