我正在尝试使用遵循此设计的分层表创建动态导航:
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
这将允许我查看子类别是否在其子类别中有任何项目,但如果他们自己有任何项目则不一定。我的实时表有很多级别,因此查询必须继续钻取类别,直到达到最后一级。如有必要,我可以提供更深入的例子。
任何帮助表示赞赏!感谢
答案 0 :(得分:1)
使用的想法是为树中的每个节点添加一串祖先(作为字符串),然后总结其中包含该节点的所有行。
;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
答案 1 :(得分:0)
在您的简单示例中,将select语句替换为下面的选择。
SELECT ,(从HCTE b中选择COUNT(),其中a.Level + 1 = b.Level)儿童来自HCTE a
它非常简单,但如果你有很多很多级别,那么它就不会很好地扩展。
但是你可以在select语句中多次引用CTE。
答案 2 :(得分:0)
我知道你接受了答案,但我会认真地看待DWH世界的this technique。
您接受的查询中有5个来自子句,并且根据优化程序如何/是否实现HCTE,您将阅读并连接相同的表几次。
该技术基本上构建了“分层索引”。像所有其他索引一样,您将花时间插入/更新/删除以节省查询时间。和所有其他索引一样,你也会花一点空间。
最后,您可以通过极快的方式获得所需的确切答案。
根据您的需要,如果汽车品牌和型号表的更新频繁且未安排,则可以通过触发器维护“索引”。或者,如果您每天加载一次表,则可以使用单个语句重建“索引”。