use*_*648 6 sql t-sql sql-server recursive-query
我正在研究一个简单的问题,并希望使用SQL来解决它.我有3个表类别,项目和关系表CategoryItem.我需要返回每个类别的项目数,但扭曲是类别按父子关系排列,子类别中的项目数应该添加到其父类别中的计数.请使用SQL考虑下面的示例数据和预期的结果集.
Id Name ParentCategoryId
1 Category1 Null
2 Category1.1 1
3 Category2.1 2
4 Category1.2 1
5 Category3.1 3
ID CateoryId ItemId
1 5 1
2 4 2
3 5 2
4 3 1
5 2 3
6 1 1
7 3 2
Run Code Online (Sandbox Code Playgroud)
结果:
CategoryNAme Count
Category1 7
Category1.1 5
Category2.1 4
Category1.2 1
Category3.1 2
Run Code Online (Sandbox Code Playgroud)
我可以在我的业务层中执行此操作,但由于数据大小,性能并非最佳.我希望如果我能在数据层中做到这一点,我将能够大大提高性能.
在此先感谢您的回复
您的表格和示例数据
create table #Category(Id int identity(1,1),Name Varchar(255),parentId int)
INSERT INTO #Category(Name,parentId) values
('Category1',null),('Category1.1',1),('Category2.1',2),
('Category1.2',1),('Category3.1',3)
create table #CategoryItem(Id int identity(1,1),categoryId int,itemId int)
INSERT INTO #CategoryItem(categoryId,itemId) values
(5,1),(4,2),(5,2),(3,1),(2,3),(1,1),(3,2)
create table #Item(Id int identity(1,1),Name varchar(255))
INSERT INTO #Item(Name) values('item1'),('item2'),('item3')
Run Code Online (Sandbox Code Playgroud)
通过递归公用表表达式检查父级的所有子级
;WITH CategorySearch(ID, parentId) AS
(
SELECT ID, ID AS ParentId FROM #Category
UNION ALL
SELECT CT.Id,CS.parentId FROM #Category CT
INNER JOIN CategorySearch CS ON CT.ParentId = CS.ID
)
select * from CategorySearch order by 1,2
Run Code Online (Sandbox Code Playgroud)
输出:针对父级的所有子级记录
ID parentId
1 1
2 1
3 1
4 1
5 1
2 2
3 2
5 2
3 3
5 3
4 4
5 5
Run Code Online (Sandbox Code Playgroud)
对结果的最终查询,计算类别及其子类别的所有项目。
;WITH CategorySearch(ID, parentId) AS
(
SELECT ID, ID AS ParentId FROM #Category
UNION ALL
SELECT CT.Id,CS.parentId FROM #Category CT
INNER JOIN CategorySearch CS ON CT.ParentId = CS.ID
)
SELECT CA.Name AS CategoryName,count(itemId) CountItem
FROM #Category CA
INNER JOIN CategorySearch CS ON CS.ParentId = CA.id
INNER JOIN #CategoryItem MI ON MI.CategoryId =CS.ID
GROUP BY CA.Name
Run Code Online (Sandbox Code Playgroud)
输出:
CategoryName CountItem
Category1 7
Category1.1 5
Category1.2 1
Category2.1 4
Category3.1 2
Run Code Online (Sandbox Code Playgroud)