2013-03-27 3 views
1

ServiceID, ParentID 및 Description이 포함 된 "Services"테이블이 있습니다. 여기서 ParentID는 다른 레코드의 ServiceID입니다. 데이터는 여러 수준의 항목 계층 구조를 형성하고 "루트"항목의 ParentID가 0으로 설정되는 방식으로 설정됩니다. 각 레코드의 루트 부모까지 모든 부모의 스레드를 표시하는 새 필드를 사용하여 쿼리를 만들 수 있습니까? 물론 루트 항목에는이 필드가 공백으로 표시됩니다.MS SQL의 한 필드에 단항 관계 계층 표시

자동차> 독일> BMW> 4 륜구동> X3

자동차> 이탈리아 : 예를 들어 자동차를 사용하여, 나는 항목 'X3'는 각각 '푼토'에 대한이 필드 내 텍스트를 가지고 싶습니다 > FIAT> 프론트 휠 드라이브> Punto

나는 ServiceID를 피드하는 함수가 있어야하고 스레드 된 설명이 포함 된 문자열 값을 얻기 위해 필요한 재귀를 수행해야한다고 생각합니다. 단항 관계 검색을 시도했지만 필요한 기능에 대한 코드 예제를 찾을 수 없습니다.

미리 감사드립니다.

업데이트 : (20처럼) 왼쪽이 어떤 합리적인 제한에 조인 사용하고 문자열 concatatinate 것

CREATE TABLE [dbo].[Services](
[ServiceID] [int] IDENTITY(1,1) NOT NULL, 
[ParentID] [int] NULL, 
[ServiceDescription] [nvarchar](250) NULL) 
+2

이에 대한 내 대답 http://stackoverflow.com/questions/14241936/how-can-i-generate-a-hierarchy-path-in-sql-that-leads-to-a을 확인 할 수 있습니다 -given-node/14243624 # 14243624 – EricZ

+0

필자는 예제를 사용하여 경로 목록을 가져 왔지만 필자가 필요로하는 것처럼 경로 테이블을 테이블과 통합하는 방법을 찾지 못했습니다. (테이블 구조를 사용하여) 방금 추가 한 업데이트를 참조하여 예제를 사용하여 다음과 같은 테이블을 얻는 방법은 무엇입니까? : ServiceID, ParentID, ServiceDescription, Path – Osprey

+1

@EricZ 예제는 단일 레코드 용입니다. 아래에 제시 한 대답은 동일한 재귀 논리이지만 표의 모든 레코드에 대한 경로를 작성하는 데 사용됩니다. –

답변

1

다음

이처럼 내 테이블 모습입니다

다음은 일반적인 예입니다. 복사, 붙여 넣기 및 실행할 수 있으며 출력이 표시됩니다. 이 방법이 효과가 있으면 상황에 맞게 작동하도록 표와 열 값을 수정할 수 있어야합니다.

If  Object_ID('dbo.Services') Is Not Null Drop Table [dbo].[Services]; 
Create Table [dbo].[Services] (ServiceID Int Identity(1,1) NOT NULL, ParenServiceID Int NULL, ServiceDescription Nvarchar(250) NULL); 

Insert [dbo].[Services] 
Select null, 'Automobiles' 
Union All 
Select 1, 'Germany' 
Union All 
Select 2, 'BMW' 
Union All 
Select 3, '4 Wheel Drive' 
Union All 
Select 1, 'Italy' 
Union All 
Select 5, 'FIAT' 
Union All 
Select 4, 'X3' 
Union All 
Select 6, 'Front Wheel Drive' 
Union All 
Select 8, 'Punto'; 

With recurCTE As 
(
     Select h.ServiceID, h2.ParenServiceID As nextParent, Convert(Varchar(max),Isnull(h2.ServiceDescription + ' > ','') + h.ServiceDescription) As Hierarchy 
     From [dbo].[Services] h 
     Left Join [dbo].[Services] h2 
       On h.ParenServiceID = h2.ServiceID 
     Union All 
     Select rc.ServiceID, h.ParenServiceID As nextParent, Convert(Varchar(max),Isnull(h.ServiceDescription + ' > ','') + rc.Hierarchy) As Hierarchy 
     From recurCTE rc 
     Join [dbo].[Services] h 
       On rc.nextParent = h.ServiceID 
),  orderedResults As 
(
     Select ServiceID, Hierarchy 
     From (Select Row_Number() Over (Partition By ServiceID Order By Len(Hierarchy) Desc) As lenPriID, 
         ServiceID, 
         Hierarchy 
       From recurCTE) As n 
     Where lenPriID = 1 
) 
Select h.*, o.Hierarchy 
From orderedResults o 
Join [dbo].[Services] h 
     On o.ServiceID = h.ServiceID 
Where ServiceDescription In ('X3','Punto'); 
+0

. 당신의 본보기는 내가 어떤 아이들 부모님이 들어갈 것인지를 안다고 가정하는 것 같습니다. 불행히도 나는 어떤 데이터가 입력 될지 모르고 레벨의 수를 알지도 못합니다. – Osprey

+0

아니요, 어린이와 부모의 관계를 가정하지 않습니다. 결과를 볼 때 이름 지정 규칙을 사용하여 명확하게 나타내었지만 원하는대로 변경할 수 있습니다. 쿼리는 테이블의 모든 값에 대한 경로 구조를 재귀 적으로 식별합니다. 3 단계 또는 100 단계가있을 수 있습니다. –

+0

오케이, 오해 받아서 죄송합니다. 당신이 무엇을 제안하고 있는지 알 수 없으므로 내 응용 프로그램을 위해 구현할 수 없다는 것이 분명합니다 (어떻게 작동하는지 모르므로). 나는 SQL 전문가가 아니다. 함수를 가지고 "ServiceID"값을 공급할 수 있으며 NVARCHAR (500)의 for에 "Path"값을 반환합니까? 테이블의 구조를 게시 한 최신 업데이트를 참조합니다. – Osprey

0

:

declare @services table (ServiceID int , ParentID int,[Description] varchar(20)) 

insert @services 
select 1,null,'automobiles' union 
select 2,null,'hotels' union 
select 3,1,'Germany' union 
select 4,3,'BMW' union 
select 5,3,'Audi' union 
select 6,2,'Hawaii' union 
select 7,2,'Australia' 

select 

s.Description+'>'+s2.Description+'>'+isnull(s3.Description,'')+'>'+isnull(s4.Description,'') 
from @services s 
left join @services s2 on (s2.ParentID=s.ServiceID) 
left join @services s3 on (s3.ParentID=s2.ServiceID) 
left join @services s4 on (s4.ParentID=s3.ServiceID) 
left join @services s5 on (s5.ParentID=s4.ServiceID) 
+0

감사. 그러나 Love2Learn에 설명했듯이, 당신의 예는 내가 어떤 아이들과 부모가 들어갈 것인지를 알고 있다고 가정하는 것 같습니다. 불행히도 그 정보가 없으며 레벨 수를 알지 못하기 때문에 EricZ에서 언급 한 것과 같은 재귀 적 접근이 필요합니다. 감사합니다. – Osprey