如何计算嵌套类别的详细信息行?

时间:2011-02-23 13:21:38

标签: tsql

让我们考虑一下我们有类别(PK为CategoryId)和Products(PK为ProductId)。此外,假设每个类别都可以与其父类别相关(使用类别中的ParentCategoryId列)。

如何才能获得类别明智的产品数量?父类别也应包括其所有子类别的所有产品的数量。

任何更简单的方法吗?

2 个答案:

答案 0 :(得分: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

试一试,如果有效,请告诉我。

<强> - 修改

好吧我想我已经得到了这个,因为它正在使用我正在使用的小型测试集。我开始看到一个我自己需要的地方,所以谢谢你提问。我承认这有点乱,但应该适用于任何级别,并且只返回最高级别的总和。

我假设产品中有一个数字字段。

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

答案 1 :(得分:1)

假设产品只能指向 sub 类别,这可能是解决问题的方法:

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

最后,它只选择祖父类别,并显示包含所有级别所有子类别的产品计数。