T-SQL - 使用运行小计查询分层表(每行有一个项目计数)

我正在尝试使用遵循此设计的分层表创建动态导航:   CREATE TABLE #CPTree(UID int,ParentID int,Name nvarchar(150),   ItemCount int)      插入#CPTree VALUES('1','0','车辆','0')      插入#CPTree VALUES('2','1','Bikes','10')      插入#CPTree VALUES('3','1','汽车','20')      插入#CPTree值('5','2','Bike Make 1','0')      插入#CPTree值('6','2','Bike Make 2','5')      插入#CPTree值('7','3','Car Make 1','0')      插入#CPTree值('8','3','Car Make 2','0')      插入#CPTree值('9','5','自行车模型A','7')      插入#CPTree值('10','5','自行车模型B','1')      插入#CPTree值('11','7','汽车模型D','4')      插入#CPTree值('12','8','Car Model X','2')       - 使用CTE检索类别/子类别的级别      ;使用HCTE(CategoryID,ParentID,Name,itemcount,Level)作为(选择   UID,ParentID,Name,itemcount,0作为来自#CPTree c的级别,其中c.UID   = 3 - 汽车类别      union all选择c.UID,c.ParentID,c.Name,c.itemcount,ch.Level + 1   来自#CPTree c内连接HCTE ch on ch.CategoryID = c.ParentID)      SELECT * FROM HCTE      DROP TABLE #CPTree       - 结束 我想检索每个类别的总项目数,例如,顶级类别'汽车'(项目数20)有2个孩子(两个项目计数为0),每个都有子项(2和4项目计数)尊敬)。汽车的总项目数量为26.同样,Car Make 1(CategoryID 7)的项目总数将为4(来自其子项的总和 - CategoryID 11)。结果将返回:   CategoryID | ParentID |名称| ItemCount |等级|   TotalItemCount      3 | 1 |汽车| 20 | 0 | 26      7 | 3 |汽车制造1 | 0 | 1 | 4      8 | 3 |汽车制造2 | 0 | 1 | 2      12 | 8 |汽车模型X | 2 | 2 | 2      11 | 7 |汽车型号D 4 | 2 | 4 这样我就可以看到子类别是否在子类别中有任何项目,但如果他们自己有任何项目则不一定。我的实时表有很多级别,因此查询必须继续钻取类别,直到达到最后一级。如有必要,我可以提供更深入的例子。 任何帮助表示赞赏!谢谢     
已邀请:
使用的想法是为树中的每个节点添加一串祖先(作为字符串),然后汇总其中包含该节点的所有行。
   ;with HCTE(CategoryID, ParentID, Name, itemcount, Level, trail)
    as
    (
     select UID, ParentID, Name, itemcount, 0 as Level, 
                                                  '/' + cast(UID as varchar(max))+ '/' as trail 
     from #CPTree c
     where c.UID = 3 -- Cars Category


union all

select c.UID, c.ParentID, c.Name, c.itemcount, ch.Level + 1, 
                                               trail + CAST(UID as varchar(max)) + '/'
from #CPTree c 
inner join HCTE ch on ch.CategoryID = c.ParentID
)
select CategoryID, ParentID, Name, ItemCount,
   (select SUM(ItemCount)
    from HCTE h2
    where charindex('/' + CAST(h1.CategoryID as varchar(max)) + '/', h2.trail, 1) <> 0
   )
 from hcte h1
    
在您的简单示例中,使用下面的选择替换您的select语句。 SELECT,(从HCTE b中选择COUNT(),其中a.Level + 1 = b.Level)儿童来自HCTE a 它非常简单,但如果你有很多很多级别,那么它就不会很好地扩展。 但是您可以在select语句中多次引用CTE。     
我知道你已经接受了答案,但我会认真地从DWH世界看这种技术。 您接受的查询有5个子句,并且根据优化程序如何/是否实现HCTE,您将阅读并连接相同的表几次。 该技术基本上构建了“分层索引”。像所有其他索引一样,您将花时间插入/更新/删除以节省查询时间。和其他所有索引一样,你也会花一点空间。 最后,您可以通过极快的方式获得所需的确切答案。 根据您的需要,如果汽车品牌和型号表的更新频繁且未计划,则可以通过触发器维护“索引”。或者,如果您每天加载一次表,则可以使用单个语句重建“索引”。     

要回复问题请先登录注册