sql - 使用sql递归计算形成树

标签 sql sql-server tsql recursive-query

我正在解决一个简单的问题,并想使用 SQL 来解决它。我有 3 个表 Category、Item 和一个关系表 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

结果:

CategoryNAme     Count
Category1          7
Category1.1        5
Category2.1        4
Category1.2        1
Category3.1        2

我可以在业务层中执行此操作,但由于数据大小,性能并不是最佳。我希望如果我能在数据层做到这一点,我将能够大大提高性能。

提前感谢您的回复

最佳答案

您的表格和示例数据

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')

通过 Recursive Commom Table Expressions 检查父级的所有子级

;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

输出:针对父级的所有子记录

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

对结果的最终查询,计算类别及其子类别的所有项目。

;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

输出:

CategoryName    CountItem
Category1           7
Category1.1         5
Category1.2         1
Category2.1         4
Category3.1         2

关于sql - 使用sql递归计算形成树,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21957255/

相关文章:

sql - T-SQL 中的最小/最大函数?

sql - 选择满足条件的行后三行

java - SQL Server 存储过程的输出参数被截断为 4000 个字符

sql-server - 如何获取事务插入的行数

java - Android 应用程序建立与服务器的连接?

sql-server - 基于集合的方法来删除包含点

sql - 将标识列添加到 SQL Server 2008 中的 View

sql - 使用 postgresql 进行表设计

mysql - 使用 Play-1.2.5 链接和查询 MySql

sql - 改进我的 SQL Select 语句以选择尚未完全完成某个部分的学生