2009-08-03 6 views
2

테이블에서 트리를 나타내는 중이므로 특정 요소의 루트 노드 (TOP ID)를 가져올 수 있어야합니다. 루트 노드는 항상 ParentIDnull입니다. 예를 들어, 테이블은 다음과 같다 경우 :SQL Server 2005에서 재귀 도움이 필요합니다.

ID ParentID 
1 null 
2 null 
3 null 
4 2 
5 1 
6 2 
7 6 
8 4 
9 8 
10 6 

ID=10TOP ID = 2; ID=9 일 때, TOP ID = 3; 등등. ID이 주어지면 TOP ID을 반환하는 SQL 서버 함수를 작성할 수 있습니까?

답변

1

SQL 2003 이전의 SQL 재귀 (예 : SQL Server 2000)는 다소 추악합니다. 트리의 각 레벨에 대해 별도의 조인 문을 원래 테이블에 다시 써야합니다. 계층 구조의 수준 수가 고정되어 있다면 이와 비슷한 것을 작성할 수 있습니다.

create table #Hell (
parent int, 
id int, 
name varchar(30) 
) 

insert into #Hell values (NULL, 1, 'The Boss') 
insert into #Hell values (1, 2, 'The Boss'' PA') 
insert into #Hell values (1, 3, 'Production Director') 
insert into #Hell values (3, 4, 'Jim''l Fixit') 


select * from #Hell H1 
inner join #Hell H2 
ON H1.id=H2.parent 
inner join #Hell H3 
ON H2.id=H3.parent 
WHERE H3.Id=4 --Find the boss for Jim 

drop table #Hell 

다행히 SQL Server 2005는 재귀 작업을 아주 쉽게 기록 할 수있는 와 공통 테이블식이있다. 참조하십시오 http://www.4guysfromrolla.com/webtech/071906-1.shtml

또한 데이터베이스에서 트리를 나타내는 다양한 방법을 알고 있어야합니다. 이 프리젠 테이션에서 SQL의 나무 슬라이드를 살펴보십시오. http://www.slideshare.net/billkarwin/sql-antipatterns-strike-back

+1

"with"연산자는 실제로 "공통 테이블 식"(CTE)이라고하며 SQL Server 관련 확장은 아니지만 SQL : 2003 Standard의 일부입니다. –

+0

나는 그것이 마이크로 소프트 일이라고 생각했지만 어떤 이유로 Postgres는 WITH RECURSIVE를 사용하는 CTE도 지원하고있다. – pjp

2

MSDN에는 Common Table Expressions을 사용하여 재귀 쿼리를 작성하는 예제가 꽤 있습니다. SQL Server 2005 이전에는 이것을 수행하는 것이 큰 어려움이었습니다 (지금은 이전 Server 2000 응용 프로그램의 정확한 문제를 다루었습니다).

0

MSDN brough up this article 이것은 우리가이 사이트에서 허용하는 형식으로 얻는 것보다 더 잘 설명 할 것입니다.

3

여기 sproc에 주어진 주어진 ID (- ID)에 대해 부모 (부모 ID = null)를 찾을 수있는 sproc의 재귀 예제가 있습니다. 네가 찾고 있는게 이거 야?

WITH recurseUp (ID, ParentID) 
    AS 
    (
     SELECT ID, ParentID 
     FROM myTable 
     WHERE ID = @ID 
     UNION ALL 
     SELECT b.ID, b.ParentID 
     FROM recurseUp a JOIN myTable b 
     ON (a.ParentID = b.ID) 
    ) 
SELECT ID FROM recurseUP WHERE ParentID is null 
+0

이 예제는 훌륭하게 작동하지만이 모든 것을 뷰 또는 SQL 함수에 넣는 것은 불가능합니까? – Vytas

0

내가 알고있는 유일한 방법은 CURSOR 및 재귀 저장 프로 시저를 사용하는 것입니다. 이것은 성능 관점 (보통)에서 일을하는 것은 정말 나쁜 방법입니다. 가능한 경우 추가 루트 부모 노드가있는 경우 코드 이동을 통해 계속 업데이트하는 데 드는 비용을 고려해야 할 수 있습니다.

+0

CTE는 2005 년 이후 서버에서 프로세스를 훨씬 더 쉽게 만듭니다. 실제로 P.I.T.A.입니다. for Sever 2000 – TheTXI

0
WITH q AS 
     (
     SELECT id, parentID 
     FROM mytable 
     WHERE id = 10 
     UNION ALL 
     SELECT mytable.id, mytable.parentid 
     FROM q 
     JOIN mytable 
     ON  mytable.parentId = q.id 
     ) 
SELECT * 
FROM q 
WHERE parentID IS NULL 
관련 문제