使用sql递归计算形成树

2024-03-08

我正在解决一个简单的问题,并想使用 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

Result:

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

检查父级的所有子级递归公用表表达式 http://technet.microsoft.com/en-us/library/ms186243%28v=sql.105%29.aspx

;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

Output:

CategoryName    CountItem
Category1           7
Category1.1         5
Category1.2         1
Category2.1         4
Category3.1         2
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用sql递归计算形成树 的相关文章

随机推荐

  • 如何生成具有特定概率密度函数的随机数?

    我正在尝试对移动无线网络的阴影和快速衰落进行建模 对于快速衰落 瑞利衰落是一个合理的模型 信道响应的包络将是瑞利分布的 将该随机变量称为 R 其概率密度函数 PDF 为 PR r 2r exp r 2 r gt 0 2 2 http en
  • Hudson 和 Maven 的双单元测试报告

    我在 hudson 有一个 maven2 项目 当 cobertura 报告插件运行时 它会导致单元测试显示它们已经运行了两次 我不介意它们运行多次 但趋势图显示的测试数量是我们实际运行的两倍 有没有办法确保图表只显示一次 thanks J
  • Oracle 中的截断表出现错误

    我遇到的问题是 当我在 Oracle 中运行以下命令时 遇到错误 Truncate table mytable Errors ORA 02266 unique primary keys in table referenced by enab
  • 眼镜检测

    我想做的是测量眼镜框的厚度 我有一个想法来测量框架轮廓的厚度 可能是更好的方法 到目前为止 我已经勾勒出眼镜框的轮廓 但线条不相交处存在间隙 我考虑过使用 HoughLinesP 但我不确定这是否是我需要的 到目前为止 我已执行以下步骤 将
  • 来自私有 GitHub 存储库的 Cordova 插件

    从私有 GitHub 存储库安装 Cordova 插件的首选方法是什么 我从供应商处购买了一个私有插件 该供应商授予我的 git 帐户访问其私有 git 存储库的权限 通常我从 cordova cli 安装插件 cordova plugin
  • 如何比较两个数组,删除相似的项目,而不迭代整个数组?

    是否可以比较两个数组并删除相等的值 如果它们位于相同的索引 而不需要迭代两个数组 这是一个例子 array1 1 2 3 4 5 6 7 23 44 array2 1 1 3 4 5 7 6 23 45 array3 sudo compar
  • 提供 if 语句问题的函数返回

    我在从 golang 的 if 语句中返回函数的预期返回语句时遇到问题 我提供了以下代码 package main import fmt func random string var x return if x return return
  • 生命周期困境与另一项活动的方向变化

    我在 tabhost 中有 2 项活动 在 Activity1 中 我处理方向变化以及用户在 Activity 之间切换时的情况 当用户从 Activity1 切换到 Activity2 通过选项卡选择 执行方向更改 然后切换回 Activ
  • 限制 python 程序的 RAM 使用

    我试图将 Python 程序的 RAM 使用量限制为一半 这样当使用所有 RAM 时它就不会完全冻结 为此我使用了以下代码 该代码不起作用 并且我的笔记本电脑仍然冻结 import sys import resource def memor
  • Haskell 中的“子类化”显示?

    可以说我有以下内容 data Greek Alpha Beta Gamma Phi deriving Show 我想使用除 Beta 之外的所有项目的默认显示 我想说 两个 我可以这样做吗 deriving Show使用标准实例化机制 简单
  • 如何在 Safari 中打开 url 并返回到 Xcode 7 中 UITests 下的应用程序?

    这是我的自定义视图 LondonStreet 是一个按钮 当我点击该按钮时 我会获取 url 并在 Safari 中打开它 它有效 然后我可以返回 使用 Back to Wishlist 按钮 它也有效 问题是当我尝试在 UITests 下
  • 如何设置 select2 下拉列表的最小宽度和最大宽度?

    我在响应式 div 中有一个 select2 下拉菜单 该 div 还有一个侧边栏元素 列 其中包含用户从下拉列表中进行的选择 他们可以选择一个选项并将其添加到侧边栏 一切正常 但我在下拉菜单中有一个很长的选项 如果用户选择此选项 则父 d
  • Woocommerce Checkout:在国家/地区下拉列表中添加占位符[重复]

    这个问题在这里已经有答案了 在我的 Woocommerce Shop 结账处有一个下拉菜单 可以选择您所在的国家 地区 默认情况下 美国已被自动选择 如何只使用 选择您所在国家 地区 的占位符 我找不到这个主题的任何解决方案有人有什么想法吗
  • 以编程方式编辑 Google 电子表格

    我编写了一个接受用户输入的程序 但现在我希望能够通过在每次用户提交表单时编辑 Google 电子表格来保存该输入 基本上 Google 电子表格会不断更新 谁能提供有关我如何实现这一目标的教程 我正在使用 Eclipse 用 Ja va 进
  • 如何在 Windows 上控制 Python 的交互式控制台输入/输出?

    我需要控制一个Windows程序 它通过调用直接从控制台读取输入 kbhit and getch from
  • 如何将列表框的值从jsp传递到servlet?

    我的 JavaScript 是 function takeListBoxValue document frmPartnerList submit var selectArray new Array for i 0 i lt partnerL
  • javascript中的${variable}是什么[重复]

    这个问题在这里已经有答案了 我见过使用 startX startY 在 JavaScript 中 这对我来说是全新的 我喜欢使用它的想法 但不知道这是证明 let cumulativePercent 0 function getCoordi
  • 如何更新 PyInstaller 生成的 exe 详细信息?

    我已经使用 PyInstaller 创建可执行文件并想要更新 exe 详细信息 例如File description File version 下面是我用过的命令 PyInstaller onefile icon favicon ico m
  • 我的 Docker 无法在 Windows 10 Pro 上启动

    我在 Windows 10 专业版 PC 上设置 Docker 时遇到了一些问题 当我尝试打开它时 我收到此崩溃报告 崩溃报告截图 https i stack imgur com uwkDZ png 这是框内的文字 System Inval
  • 使用sql递归计算形成树

    我正在解决一个简单的问题 并想使用 SQL 来解决它 我有 3 个表 Category Item 和一个关系表 CategoryItem 我需要返回每个类别的项目计数 但问题是类别按父子关系排列 并且子类别中的项目计数应添加到其父类别中的计