그룹 및 집계 및 합계 및 합계 데이터의 가장 좋은 방법은 무엇입니까?
-
05-07-2019 - |
문제
자체 참조 테이블이 주어졌습니다
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에 가져 와서 재귀를 수행하는 것이 좋습니다.