2011-02-23 3 views
1

카테고리 (PK를 카테고리 ID로 사용)와 제품 (PK를 제품 ID로 사용)이 있다고 가정 해 보겠습니다. 또한 모든 카테고리가 상위 카테고리와 관련 될 수 있다고 가정합니다 (카테고리의 ParentCategoryId 열 사용).중첩 된 범주의 세부 행을 계산하는 방법은 무엇입니까?

카테고리 별 제품 수는 어떻게 얻을 수 있습니까? 상위 카테고리에는 모든 하위 카테고리의 모든 제품 수를 포함해야합니다.

더 쉬운 방법은 없나요?

답변

2

는이 COLB 콜라에 대한 롤업 합계 합계를 줄 것이다

select cola, colb, SUM(colc) AS sumc 
from table 
group by cola, colb 
with rollup 

롤업

에 대한 좋은 사용하는 것을 요구하고 무엇을 같은 소리. 아래 예제 결과. 희망 포맷. null 값은 그룹의 롤업 합계입니다.

cola colb sumc 
1  a  1 
1  b  4 
1  NULL 5 
2  c  2 
2  d  3 
2  NULL 5 
NULL NULL 10 

효과가 있는지 알려주세요. OK --edit

는 나는 내가 사용하고 작은 테스트 세트에 노력하고 있습니다로 필자가이 거 같아요. 필자는 나 자신이 필요로하는 곳을보기 시작했다. 나는 이것이 다소 지저분하지만 어느 수준의 숫자에서나 작동해야하며 최고 수준의 합계만을 반환 할 것이라고 인정할 것이다.

제품에 숫자 입력란이 있다고 가정했습니다.

with x 
as (
    select c.CategoryID, c.parentid, p.number, cast(c.CategoryID as varchar(8000)) as grp, c.CategoryID as thisid 
    from Categories as c 
    join Products as p on p.Categoryid = c.CategoryID 
union all 
    select c.CategoryID, c.parentid, p.number, cast(c.CategoryID as varchar(8000))+'.'+x.grp , x.thisid 
    from Categories as c 
    join Products as p on p.Categoryid = c.CategoryID 
    join x on x.parentid = c.CategoryID 
) 
select x.CategoryID, SUM(x.number) as Amount 
from x 
left join Categories a on (a.CategoryID = LEFT(x.grp, case when charindex('.',x.grp)-1 > 0 then charindex('.',x.grp)-1 else 0 end)) 
        or (a.CategoryID = x.thisid) 
where a.parentid = 0 
group by x.CategoryID 
+0

나는 내 질문에 정확하게 틀을 맞추지 않았다고 생각한다. 나는 그것을 사과한다. 간단히 말해 "CategoryId, Count (Products)"열이있는 출력이 필요합니다. 제품 수에는 현재 카테고리 및 모든 하위 카테고리의 모든 제품이 포함됩니다. – user203687

+0

여러 수준의 범주 (조부모 - 부모 - 자식)가 있습니까? 아니면 한 수준 (부모 - 자식) 만 들고 계십니까? – AgentDBA

+0

예.여러 카테고리의 카테고리가 있습니다. 그러나 제품은 항상 하나의 카테고리 (범주는 그랜드 부모, 부모 또는 자식이 될 수 있음)에 속합니다. – user203687

1

제품은 하위 카테고리를 가리 만 할 수 있다고 가정하면, 여기에 문제에 대한 가능한 해결책은 다음과 같습니다

SELECT 
    cp.CategoryId, 
    ProductCount = COUNT(*) 
FROM Products p 
    INNER JOIN Categories cc ON p.CategoryId = cc.CategoryId 
    INNER JOIN Categories cp ON cc.ParentCategoryId = cp.CategoryId 
GROUP BY cp.CategoryId 

그러나

위의 가정은 잘못이며, 제품은 상위 범주를 참조 할 수있는 경우

SELECT 
    CategoryId = ISNULL(c2.CategoryId, c1.CategoryId), 
    ProductCount = COUNT(*) 
FROM Products p 
    INNER JOIN Categories c1 ON p.CategoryId = c1.CategoryId 
    LEFT JOIN Categories c2 ON c1.ParentCategoryId = c2.CategoryId 
GROUP BY ISNULL(c2.CategoryId, c1.CategoryId) 

: 직접뿐만 아니라 하위 범주로, 여기에 당신이이 경우에 제품을 셀 수 방법 5,

EDIT

이것은 카테고리 (카테고리, 서브 카테고리, 서브 - 서브 - 카테고리)의 계층 구조의 레벨 3에 대해 작동한다.

SELECT 
    CategoryId = COALESCE(c3.CategoryId, c2.CategoryId, c1.CategoryId), 
    ProductCount = COUNT(*) 
FROM Products p 
    INNER JOIN Categories c1 ON p.CategoryId = c1.CategoryId 
    LEFT JOIN Categories c2 ON c1.ParentCategoryId = c2.CategoryId 
    LEFT JOIN Categories c3 ON c2.ParentCategoryId = c3.CategoryId 
GROUP BY ISNULL(c3.CategoryId, c2.CategoryId, c1.CategoryId) 

COALESCE은 첫 번째 비 NULL 구성 요소를 선택합니다. 카테고리가 하위 인 경우 c3.Category을 선택합니다. 상위 인 경우 상위 - 부모 인 경우 c2.Category이 선택되고 그렇지 않으면 상위 - 부모 (c1.CategoryId)입니다.

결국 그랜드 부모 카테고리 만 선택하고 모든 레벨의 모든 하위 카테고리가 포함 된 제품 수를 보여줍니다.

+0

제품이 한 범주에만 속합니다 (카테고리는 조부모, 부모 또는 자녀 일 수 있음). 첫 번째 기능은 여전히 ​​작동합니까 (중첩 된 하위 카테고리 용)? – user203687

+0

@ user203687 : 두 솔루션 모두 두 가지 수준의 계층에 대한 것입니다. 다른 하나를 추가했습니다. –

관련 문제