2009-10-23 6 views
1

는 관련 값트리 데이터를 그룹화하고 집계 및 합계하는 가장 좋은 방법은 무엇입니까?

ItemValue 
------------- 
ItemId (fk) 
Amount 

그리고 일부 샘플 데이터

Item      ItemValues 
Id  ParentId   ItemId  Amount 
--------------------  ---------------------- 
1  null    1   10 
2  1     3   40 
3  1     3   20 
4  2     4   10 
5  2     5   30 
6  null 
7  6 
8  7 

내가 Item.Id을 가지고 직접적인을 반환하는 sproc에 필요의 관련 테이블 자체 참조 테이블

Item 
------------- 
Id (pk) 
ParentId (fk) 

을 감안할 때 아이들은 모두 ItemValue.Amounts의 합계를 가지고 있으며, 자녀와 자녀는 tr 아래로 내려갑니다. ee. 예를 들어

, 1가 전달되는 경우, 나무가 될 것이다 2, 3, 4, 5 직접 아이들은 2, 3 출력이 동작을 달성하기 위해 적용되어야한다 방법 어떤 종류의

ItemId Amount 
------------------ 
2   40  (values from ItemIds 4 & 5) 
3   60  (values from ItemId 3) 

것입니까?

CTE 사용을 고려하고 있지만 더 빠르고 더 빠른 방법이 있는지 궁금합니다.

+0

SQL Server 2005도 다시 – Bob

답변

5

이와 같은 재귀 CTE가 작동 것이다, 계층 구조를 가정하는 것은 너무 깊이하지 않습니다

declare @ParentId int; 
set @ParentId = 1; 

;with 
    Recurse as (
    select 
     a.Id as DirectChildId 
    , a.Id 
    from Item a 
    where ParentId = @ParentId 
    union all 
    select 
     b.DirectChildId 
    , a.Id 
    from Item a 
    join Recurse b on b.Id = a.ParentId 
    ) 
select 
    a.DirectChildId, sum(b.Amount) as Amount 
from Recurse a 
left join ItemValues b on a.Id = b.ItemId 
group by 
    DirectChildId; 

비 CTE 방법을 반복의 형태를 요구, 커서 기반 또는 그렇지. 저장 프로 시저이기 때문에 가능한 많은 데이터가 반복되는 경우 데이터를 적절히 조각화하는 한 더 잘 확장됩니다.

클러스터 된 인덱스가 Id 인 경우 ParentId에 클러스터되지 않은 인덱스를 추가하십시오. 커버링 인덱스로서, 북마크 룩업을 통한 초기 탐색을 만족시킬 것입니다. 클러스터 된 인덱스는 재귀 조인을 도와줍니다.

클러스터 된 인덱스가 이미 ParentId에있는 경우 Id에 클러스터되지 않은 인덱스를 추가하십시오. 함께, 그들은 사실상 위의 것과 같습니다. ItemValues의 경우 실제 테이블이 이보다 넓은 경우 (ItemId) INCLUDE (Amount)에 대한 인덱스를 원할 수 있습니다.

+0

"계층 구조가 너무 깊어지지 않는다고 가정합니다"라고 다시 태그 할 것입니다. 그렇지 않은 경우 문제가 발생하지만 어떻게됩니까? – Bob

+0

SQL Server에서 재귀 깊이는 기본적으로 100으로 제한됩니다. MAXRECURSION 쿼리 힌트로 32767까지 지정할 수 있지만 특정 임계 값보다 큰 볼륨으로 선형 확장되지 않는다고 가정합니다. 그러나 한 번에 한 명의 부모를 지정하게되므로 상황에 따라 문제가되지는 않습니다. 제대로 색인을 생성하고 재귀 깊이가 합리적인 수준 (100 미만?)이면 성능이 문제가되지 않습니다. –

+0

굉장합니다, 고마워요! – Bob

0

데이터를 중첩 세트 모델로 저장할 수 있습니까? (여기는 MySQL reference이지만 아이디어는 데이터베이스 전반에서 공통적입니다)? 그렇다면 당신이 찾고있는 가치를 찾는 작업은 매우 간단합니다.

+0

불행히도 지금 구조가 설정되어 있습니다. – Bob

0

데이터베이스에서 처리해야합니까? 필요한 데이터를 BLL에 가져 와서 재귀를 수행하는 것이 좋습니다.

관련 문제