문제

자체 참조 테이블이 주어졌습니다

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

관련 값의 관련 테이블이 있습니다

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 그리고 직접 어린이들에게 모두의 합으로 돌아갑니다 ItemValue.Amounts 그들, 그들의 자녀들과 아이들은 나무 아래로 내려갑니다.

예를 들어, if 1 통과되면 나무가있을 것입니다 2, 3, 4, 5 직접 아이들은입니다 2, 3 출력이 될 것입니다

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

이 행동을 달성하기 위해 어떤 종류의 접근 방식을 적용해야합니까?

CTE 사용을 고려하고 있지만 더 나은 접근 방식이 있는지 궁금합니다.

도움이 되었습니까?

해결책

계층 구조가 너무 깊지 않다고 가정하면 이와 같은 재귀적인 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 방법에는 일부 형태의 반복, 커서 기반 또는 기타 형태가 필요합니다. 그것은 저장된 Proc, 그 가능성이며, 재발 할 데이터가 많으면 데이터를 적절하게 슬라이스하는 한 더 잘 확장 될 것입니다.

클러스터 된 인덱스가 ID에 있으면 ParentID에 비 클러스터 된 인덱스를 추가하십시오. 커버링 인덱스로서, 책갈피 조회와 함께 초기 찾기를 만족시킬 것입니다. 클러스터 된 인덱스는 재귀 조인을 도와줍니다.

클러스터 된 인덱스가 이미 ParentID에있는 경우 ID에 비 클러스터 인덱스를 추가하십시오. 함께, 그것들은 거의 위의 것과 동일합니다. ItemValues의 경우 실제 테이블이 이것보다 넓은 경우 (itemid) 포함 (금액)를 포함 할 수 있습니다.

다른 팁

중첩 세트 모델에서 데이터를 저장할 수 있습니까 (여기 MySQL이 있습니다. 참조 그러나 아이디어는 데이터베이스에서 일반적입니다)? 그렇다면 원하는 값을 찾는 작업은 상당히 간단합니다.

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

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top