2011-02-23 74 views
1

讓我們考慮我們有類別(PK爲CategoryId)和產品(PK爲ProductId)。另外,假設每個類別都可以與其父類別相關(使用類別中的ParentCategoryId列)。如何計算嵌套類別上的詳細行數?

如何獲得類別明智的產品數量?父類別也應該包括所有子類別的所有產品的數量。

任何更簡單的方法呢?

回答

2

聽起來像你問的是與彙總

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

這將給予總和COLB而可樂彙總和良好的使用。下面的示例結果。希望格式化工作。空值是該組的彙總總和。

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

給它一個去,讓我知道如果這工作。

--edit

OK,我認爲香港專業教育學院得到這個,因爲它正在我使用一個小的測試集。我開始看到自己需要這個地方,所以謝謝你提出這個問題。我承認這有點亂,但應該適用於任何級別的數據,並且只會返回最高級別的總和。

我做了一個假設,即產品中有一個數字字段。

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 2011-02-23 15:26:47

+0

是否有多個級別(祖父母 - 父母 - 子女)還是隻有一個級別(父母 - 子女)? – AgentDBA 2011-02-23 15:42:24

+0

是的。我有多個級別的類別。但產品總是屬於一個類別(類別可能是祖父母,父母或子女)。 – user203687 2011-02-23 16:16:29

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) 

編輯

這應該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 2011-02-23 16:20:50

+0

@ user203687:這兩種解決方案僅適用於兩種層次結構。又增加了一個。 – 2011-02-23 17:05:48