2014-01-27 2 views
0

Aaaack.자체 참조/CTE/매핑 된 하나의 엔터티에 대한 흔적 찾기

나는 두뇌 동결 순간을 보내고 있습니다.

아래에는 자체 참조 테이블이 있습니다. 그리고 자발적으로 가입하고 정보를 얻을 수있는 CTE가 있습니다.

내가 얻으려고하는 것은 한 사람을위한 "완전한 계층 경로"입니다.

미리 지정된 수의 레벨이 없습니다. (아래의 예제가 만들어져 있습니다. 소금물로 위치 관계에있는 사람을 데려가십시오 ~ 내 데이터 구조를 나타냅니다. 내 실제 데이터 구조가 아닙니다.)

@PersonUUID_Me는 "Town "수준 인 반면 @PersonUUID_Nobody는 거리 수준에 매핑됩니다. 일명, 2 명의 다른 사람들은 그들의 계층 구조에 대해 2 개의 서로 다른 행 수를 가지고 있습니다. 그래서 나는 "Depth"가 3 인 (또는 어떤 것이 든 미리 결정된) 뱅킹을 할 수 없다.

지금 내가 얻는 것은 Person_Me의 "하단"행에 불과합니다.

99999999-9999-9999-9999-999999999999 USA (NULL) 0 
AAAAAAAA-8888-8888-8888-888888888888 Virginia 99999999-9999-9999-9999-999999999999 1 
AAAAAAAA-7777-7777-7777-777777777777 Shenandoah AAAAAAAA-8888-8888-8888-888888888888 2 
AAAAAAAA-6666-6666-6666-666666666666 Strasburg AAAAAAAA-7777-7777-7777-777777777777 3 

을하고 난 Person_Nobody을 위해 그것을 실행 한 경우 (도시하지 않음), 내가 얻을 것 :

99999999-9999-9999-9999-999999999999 USA (NULL) 0 
BBBBBBBB-8888-8888-8888-888888888888 North Carolina 99999999-9999-9999-9999-999999999999 1 
BBBBBBBB-7777-7777-7777-777777777777 Wake BBBBBBBB-8888-8888-8888-888888888888 2 
BBBBBBBB-6666-6666-6666-666666666666 Raleigh BBBBBBBB-7777-7777-7777-777777777777 3 
BBBBBBBB-5555-5555-5555-555555555555 Main St BBBBBBBB-6666-6666-6666-666666666666 4 

Gaaaa을 내가 좀하고 싶습니다 무엇

AAAAAAAA-6666-6666-6666-666666666666 Strasburg AAAAAAAA-7777-7777-7777-777777777777 3 

. 나는 기본적인 것을 놓치고있어, 알아.하지만 나는 뇌가 얼었다.

다시 한 사람을 위해 완전한 계층 추적을 얻으려고하고 있는데 그 사람은 "맨 아래"계층 구조 요소에 매핑됩니다 ..... 그러나 그 요소의 "깊이"는 사전이 아닙니다 -결정된. 이 예에서는 "내가 가장 잘 알고있는 계층 구조 값을 매핑하겠습니다. 그러나 가장 상세한 정보 (거리)를 알지 못해서 주나 타운을 알 수 있습니다.

-- START TSQL 

SET NOCOUNT ON 

IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'[dbo].[Person]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) 
BEGIN 
DROP TABLE [dbo].[Person] 
END 



IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'[dbo].[BreadCrumbTrail]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) 
BEGIN 
DROP TABLE [dbo].[BreadCrumbTrail] 
END 
GO 



CREATE TABLE [dbo].[BreadCrumbTrail] ( 
     [BreadCrumbTrailSurrogateUUID] [uniqueidentifier] NOT NULL 
    , [BreadCrumbTrailName] varchar(64) NOT NULL 
    , [CreateDate] [datetime] NOT NULL 
    , ParentBreadCrumbTrailSurrogateUUID [uniqueidentifier] NULL 

) 


GO 

ALTER TABLE dbo.BreadCrumbTrail ADD CONSTRAINT PK_BreadCrumbTrail PRIMARY KEY NONCLUSTERED (BreadCrumbTrailSurrogateUUID) 
GO 

ALTER TABLE [dbo].[BreadCrumbTrail] ADD CONSTRAINT FK_BreadCrumbTrail_SelfRef FOREIGN KEY ([ParentBreadCrumbTrailSurrogateUUID]) REFERENCES dbo.[BreadCrumbTrail] (BreadCrumbTrailSurrogateUUID) 
GO 


IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'[dbo].[Person]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) 
BEGIN 
DROP TABLE [dbo].[Person] 
END 


CREATE TABLE [dbo].[Person] ( 

    [PersonUUID] [uniqueidentifier] NOT NULL, 
    [BreadCrumbTrailSurrogateUUID] [uniqueidentifier] NOT NULL, 
    [LastName] [varchar](64) NOT NULL, 
    [FirstName] [varchar](64) NOT NULL, 
    [CreateDate] [datetime] NOT NULL 
    ) 

GO 

ALTER TABLE dbo.Person ADD CONSTRAINT PK_Person PRIMARY KEY NONCLUSTERED (PersonUUID) 
GO 

ALTER TABLE [dbo].Person ADD CONSTRAINT FK_Person_To_BreadCrumb FOREIGN KEY ([BreadCrumbTrailSurrogateUUID]) REFERENCES dbo.[BreadCrumbTrail] (BreadCrumbTrailSurrogateUUID) 
GO 




declare @PersonUUID_Me [uniqueidentifier] 
select @PersonUUID_Me = '11111111-1111-1111-1111-111111111111' 

declare @PersonUUID_Nobody [uniqueidentifier] 
select @PersonUUID_Nobody = '22222222-2222-2222-2222-222222222222' 

declare @BreadCrumbTrailSurrogateUUID_Country [uniqueidentifier] 
select @BreadCrumbTrailSurrogateUUID_Country = '99999999-9999-9999-9999-999999999999' 
declare @BreadCrumbTrailSurrogateUUID_State1 [uniqueidentifier] 
select @BreadCrumbTrailSurrogateUUID_State1 = 'AAAAAAAA-8888-8888-8888-888888888888' 
declare @BreadCrumbTrailSurrogateUUID_County1 [uniqueidentifier] 
select @BreadCrumbTrailSurrogateUUID_County1 = 'AAAAAAAA-7777-7777-7777-777777777777' 
declare @BreadCrumbTrailSurrogateUUID_Town1 [uniqueidentifier] 
select @BreadCrumbTrailSurrogateUUID_Town1 = 'AAAAAAAA-6666-6666-6666-666666666666' 

declare @BreadCrumbTrailSurrogateUUID_State2 [uniqueidentifier] 
select @BreadCrumbTrailSurrogateUUID_State2 = 'BBBBBBBB-8888-8888-8888-888888888888' 
declare @BreadCrumbTrailSurrogateUUID_County2 [uniqueidentifier] 
select @BreadCrumbTrailSurrogateUUID_County2 = 'BBBBBBBB-7777-7777-7777-777777777777' 
declare @BreadCrumbTrailSurrogateUUID_Town2 [uniqueidentifier] 
select @BreadCrumbTrailSurrogateUUID_Town2 = 'BBBBBBBB-6666-6666-6666-666666666666' 

declare @BreadCrumbTrailSurrogateUUID_Street2 [uniqueidentifier] 
select @BreadCrumbTrailSurrogateUUID_Street2 = 'BBBBBBBB-5555-5555-5555-555555555555' 



INSERT INTO [dbo].[BreadCrumbTrail] ( 
     [BreadCrumbTrailSurrogateUUID] 
    , [BreadCrumbTrailName] 
    , [CreateDate] 
    , ParentBreadCrumbTrailSurrogateUUID 
    ) 
Select @BreadCrumbTrailSurrogateUUID_Country , 'USA' , CURRENT_TIMESTAMP , NULL 
UNION ALL Select @BreadCrumbTrailSurrogateUUID_State1 , 'Virginia' , CURRENT_TIMESTAMP , @BreadCrumbTrailSurrogateUUID_Country 
UNION ALL Select @BreadCrumbTrailSurrogateUUID_County1 , 'Shenandoah' , CURRENT_TIMESTAMP , @BreadCrumbTrailSurrogateUUID_State1 
UNION ALL Select @BreadCrumbTrailSurrogateUUID_Town1, 'Strasburg' , CURRENT_TIMESTAMP , @BreadCrumbTrailSurrogateUUID_County1 
UNION ALL Select @BreadCrumbTrailSurrogateUUID_State2 , 'North Carolina' , CURRENT_TIMESTAMP , @BreadCrumbTrailSurrogateUUID_Country 
UNION ALL Select @BreadCrumbTrailSurrogateUUID_County2 , 'Wake' , CURRENT_TIMESTAMP , @BreadCrumbTrailSurrogateUUID_State2 
UNION ALL Select @BreadCrumbTrailSurrogateUUID_Town2, 'Raleigh' , CURRENT_TIMESTAMP , @BreadCrumbTrailSurrogateUUID_County2 
UNION ALL Select @BreadCrumbTrailSurrogateUUID_Street2, 'Main St' , CURRENT_TIMESTAMP , @BreadCrumbTrailSurrogateUUID_Town2 


INSERT INTO [dbo].[Person] ( [PersonUUID] , [BreadCrumbTrailSurrogateUUID] , [LastName] , [FirstName] , [CreateDate]) 
      Select @PersonUUID_Me , @BreadCrumbTrailSurrogateUUID_Town1 , 'Coder', 'Granada' , CURRENT_TIMESTAMP 
UNION ALL Select @PersonUUID_Nobody , @BreadCrumbTrailSurrogateUUID_Street2 , 'Body', 'No' , CURRENT_TIMESTAMP 




/* 
Select [PersonUUID] , [BreadCrumbTrailSurrogateUUID] , [LastName] , [FirstName] , [CreateDate] 
from [dbo].[Person] per 
    where per.PersonUUID = @PersonUUID_Me 
*/ 




;WITH cteLocation (BreadCrumbTrailSurrogateUUID, [BreadCrumbTrailName] , ParentBreadCrumbTrailSurrogateUUID , Depth) 
AS 
(
    Select bc1.BreadCrumbTrailSurrogateUUID, bc1.[BreadCrumbTrailName], bc1.ParentBreadCrumbTrailSurrogateUUID , 0 as Depth From dbo.BreadCrumbTrail bc1 where bc1.ParentBreadCrumbTrailSurrogateUUID IS NULL 
    Union ALL 
    Select bc2.BreadCrumbTrailSurrogateUUID, bc2.[BreadCrumbTrailName] , bc2.ParentBreadCrumbTrailSurrogateUUID , Depth + 1 
    From dbo.BreadCrumbTrail bc2 
    inner join cteLocation cteL on bc2.ParentBreadCrumbTrailSurrogateUUID = cteL.BreadCrumbTrailSurrogateUUID 
) 

Select cteLoc.BreadCrumbTrailSurrogateUUID, [BreadCrumbTrailName] , ParentBreadCrumbTrailSurrogateUUID , Depth 
from cteLocation cteLoc 
join [dbo].[Person] per on per.BreadCrumbTrailSurrogateUUID = cteLoc.BreadCrumbTrailSurrogateUUID 
    where per.PersonUUID = @PersonUUID_Me 
+0

내가 그렇게 슈퍼 간단한 결국 아니었다 생각을 – granadaCoder

+0

내가 여기에 유사한 게시물을 발견 : HTTP : //www.sqlservercentral .com/Forums/Topic1075989-203-6.aspx 해당 게시물에서 답변을 받으면 여기에서 업데이트 (적절한 크레딧 제공)하겠습니다. – granadaCoder

답변

1

당신은 사람까지 계층 구조에서 역 추적하는 또 다른 CTE가 필요합니다.

;WITH cteLocation (BreadCrumbTrailSurrogateUUID, [BreadCrumbTrailName] , ParentBreadCrumbTrailSurrogateUUID , Depth) 
AS 
(
    Select bc1.BreadCrumbTrailSurrogateUUID, bc1.[BreadCrumbTrailName], bc1.ParentBreadCrumbTrailSurrogateUUID , 0 as Depth From dbo.BreadCrumbTrail bc1 where bc1.ParentBreadCrumbTrailSurrogateUUID IS NULL 
    Union ALL 
    Select bc2.BreadCrumbTrailSurrogateUUID, bc2.[BreadCrumbTrailName] , bc2.ParentBreadCrumbTrailSurrogateUUID , Depth + 1 
    From dbo.BreadCrumbTrail bc2 
    inner join cteLocation cteL on bc2.ParentBreadCrumbTrailSurrogateUUID = cteL.BreadCrumbTrailSurrogateUUID 
) 
,ctePerson as 
(
    Select cteLoc.BreadCrumbTrailSurrogateUUID, [BreadCrumbTrailName] , ParentBreadCrumbTrailSurrogateUUID , Depth 
    from cteLocation cteLoc 
    join [dbo].[Person] per on per.BreadCrumbTrailSurrogateUUID = cteLoc.BreadCrumbTrailSurrogateUUID 
    where per.PersonUUID = @PersonUUID_Nobody 

    union all 

    Select c.BreadCrumbTrailSurrogateUUID, c.[BreadCrumbTrailName], c.ParentBreadCrumbTrailSurrogateUUID, c.Depth 
    from cteLocation c 
    inner join ctePerson p on c.BreadCrumbTrailSurrogateUUID = p.ParentBreadCrumbTrailSurrogateUUID 
) 
select * 
from ctePerson 
order by Depth 
+0

교외의 친구를 고소하십시오. – granadaCoder

관련 문제