SQLServer树形数据结构的数据进行数据统计
前言
前几天朋友问我,关于SQLServer数据库中对树形结构的表数据统计问题,需求大致如下:
分类表(递归数据),A的子分类是B,B的子分类是C……分类关系不间断,A为第一层,B为第二层,C为第三层……需要统计“每个分类所在的层数”、“子分类的总数”和“子分类的层数”。
解决思路:
创建示例表结构,代码如下:
-- 分类示例表
create table temp_class
(
classId int primary key identity(1,1), -- 分类ID,主键,递增
className nvarchar(50), -- 分类名称
pcId int default 0, -- 父级分类ID,0表示最顶层
uLevel int, -- 层数
nextUCount int, -- 子分类的总数
nextLevelCount int -- 子分类的层数
);
-- 层数字段添加索引
-- create index ind_tempClass_uLevel on temp_class(uLevel); -- 添加测试数据。。。。。。
步骤一:每个分类所在的层数
根据树形数据结构的规律,在统计层数时,需要从最顶层向下累计,代码如下:
-- 1、更新层数(pcId=0 表示第一层)
-- 更新最顶层
declare @i int=1; -- 第一层
update temp_class set uLevel=@i where pcId=0;
while(1=1)
begin
if(not exists(select top 1 1 from temp_class a where exists(select top 1 1 from temp_class b where b.uLevel=@i and b.classId=a.pcId)))
break; -- 无下层数据,跳出循环
-- 更新下一层
update a set a.uLevel=@i+1 from temp_class a where exists(select top 1 1 from temp_class b where b.uLevel=@i and b.classId=a.pcId);
-- 增加一层
set @i=@i+1;
end;
步骤二:子分类的总数
在第一步中,已经统计出了分类的层数,在统计每个分类的子分类个数时,就从最底层统计起来,本层子分类的个数就等于下一层中子分类的个数之和加上下一层的分类数量,代码如下:
-- 2、更新子分类的总数
-- 获取最低层分类(最大的层数)
declare @maxLevel int=1;
select @maxLevel=MAX(uLevel) from temp_class;
-- 更新最底层的子分类总数为 0
update temp_class set nextUCount=0 where uLevel=@maxLevel;
-- 从最底层向上累计子分类总数
while(1=1)
begin
set @maxLevel=@maxLevel-1;
if(@maxLevel<=0) -- 层数走完,退出
break;
-- 更新上一层的子分类的总数
update a set a.nextUCount=isnull(b.nextUCount,0) from temp_class a
left join
-- 父级(本层)分类的个数=下一层中子分类的个数之和+下一层的分类数量
(select pcId,SUM(nextUCount)+COUNT(classId) nextUCount from temp_class where uLevel=@maxLevel+1 group by pcId) b
on a.classId=b.pcId
where a.uLevel=@maxLevel;
end;
步骤三:子分类的层数
在第一步中,已经统计出了分类的层数,在统计每个分类的子分类层数时,就从最底层统计起来,本层子分类的层数就等于下一层中子分类的层数最大值加上一层,代码如下:
-- 3、更新子分类的层数
-- 获取最低层子分类(最大的层数)
declare @maxLevel int=1;
select @maxLevel=MAX(uLevel) from temp_class;
-- 更新最底层的子分类层数为 0
update temp_class set nextLevelCount=0 where uLevel=@maxLevel;
-- 从最底层向上累计层数
while(1=1)
begin
set @maxLevel=@maxLevel-1;
if(@maxLevel<=0) -- 层数走完,退出
break;
-- 更新上一层的子分类层数
update a set a.nextLevelCount=ISNULL(b.nextLevelCount,0) from temp_class a
left join
-- 父级(本层)分类的层数=下一层中子分类的最大层数+1(当前子分类为 1 层)
(select pcId,(MAX(nextLevelCount)+1) as nextLevelCount from temp_class where uLevel=@maxLevel+1 group by pcId) b
on a.classId=b.pcId
where a.uLevel=@maxLevel;
end;
查询结果:

后言
该随笔仅当个人笔记所用,路过的大神如有好的建议,还请赐教,菜鸟再此感激不尽!
SQLServer树形数据结构的数据进行数据统计的更多相关文章
- SQLSERVER是怎麽通过索引和统计信息来找到目标数据的(第三篇)
SQLSERVER是怎麽通过索引和统计信息来找到目标数据的(第三篇) 最近真的没有什么精力写文章,天天加班,为了完成这个系列,硬着头皮上了 再看这篇文章之前请大家先看我之前写的第一篇和第二篇 第一篇: ...
- 不制作证书是否能加密SQLSERVER与客户端之间传输的数据?
不制作证书是否能加密SQLSERVER与客户端之间传输的数据? 在做实验之前请先下载network monitor抓包工具 微软官网下载:http://www.microsoft.com/en-us/ ...
- SharePoint2010沙盒解决方案基础开发——关于TreeView树形控件读取列表数据(树形导航)的webpart开发及问题
转:http://blog.csdn.net/miragesky2049/article/details/7204882 SharePoint2010沙盒解决方案基础开发--关于TreeView树形控 ...
- SQLSERVER手动增长日志文件和数据文件
原文:SQLSERVER手动增长日志文件和数据文件 SQLSERVER手动增长日志文件和数据文件 手动增长日志文件,实际上就是修改日志文件的大小 size 的单位是MB 下面设置日志文件大小是204 ...
- 使用SQLServer 2008的CDC功能实现数据变更捕获
原文:使用SQLServer 2008的CDC功能实现数据变更捕获 最近由于工作需要,研究了一下2008 CDC功能,觉得还不错,下面整理了一下研究过程,虽然比较粗略,但是基本上能用了,如果有补充请大 ...
- SQLServer通过链接服务器远程删除数据性能问题解决
原文:SQLServer通过链接服务器远程删除数据性能问题解决 在上一遍文章中介绍了SQLServer通过链接服务器访问Oracle性能问题的解决方法,本文介绍链接服务器下远程删除SQLServer数 ...
- SQLServer中处理亿万级别的数据
在SQLServer中处理亿万级别的数据(历史数据),可以按以下方面进行: 去掉表的所有索引 用SqlBulkCopy进行插入 分表或者分区,减少每个表的数据总量 在某个表完全写完之后再建立索引 正确 ...
- SQLServer转MYSQL的方法(连数据)[传]
转自 https://blog.csdn.net/AlbenXie/article/details/77449720 SQLServer转MYSQL的方法(连数据) 本次转换需要依赖使用工具Navic ...
- 用servlet来提取数据,并作统计,然后用jfreechart画图
指定时间范围的数据提取,并做统计: 用servlet来提取数据,并作统计,然后用jfreechart画图. 使用的话,需要在web.xml里面配置相应的servlet,并且在index.jsp页面做引 ...
随机推荐
- 纯JS写最简单的图片轮播
非常简单的一个大图轮播,通过将控制显示位置来进行轮播效果,写来给正在学习的新手朋友们参考交流. 先看效果:(实际效果没有这么快) 先看布局: <div id="display" ...
- Andorid自动读取短信验证码
手机收到验证码短信后,程序自动识别验证码并填充验证码输入框. 思路是有了,实现的方式也有多种: 1.开启一个线程,隔一段时间就去查询收件箱是否有变化,有变化再读取出来做处理. 2.注册一个短信变化的广 ...
- jenkins容器权限被被拒绝
问题,我们从官网上面pull下jenkins后,如果直接运行容器的没问题 docker run -d -p 8080:8080 -v jenkins:latest 不过我们可能需要映射下容器内部的地址 ...
- EM最大期望算法-走读
打算抽时间走读一些算法,尽量通俗的记录下面,希望帮助需要的同学. overview: 基本思想: 通过初始化参数P1,P2,推断出隐变量Z的概率分布(E步): 通过隐变量Z的概 ...
- WebGL 创建和初始化着色器过程
1.编译GLSL ES代码,创建和初始化着色器供WebGL使用.这些过程一般分为7个步骤: 创建着色器对象(gl.createBuffer()); 向着色器对象中填充着色器程序的源代码(gl.shad ...
- JS实现轻量级计算器
想尝试做一个网页版计算器后,参考了很多博客大神的代码,综合归纳.总结修改,整理如下文. 附: Demo 源码 一.HTML+CSS 具体结构样式如下图,基本参照手机计算器界面.按钮功能可以查 ...
- Python 安装虚拟环境
写在前面: 安装指南是在 Ubuntu 下面操作的.不同的 Linux 版本,安装指令不同.所以,该指南的某些指令对于像 CentOS 等非 Ubuntu 系统不适用. 为什么需要使用虚拟环境? 虚拟 ...
- 现代3D图形编程学习--opengl使用不同的缓存对象(译者添加)
现代3D图形编程学习系列翻译地址 http://www.cnblogs.com/grass-and-moon/category/920962.html opengl使用不同的缓存对象 在设置颜色一章中 ...
- 使用mysql索引技巧及注意事项
一.索引的作用 一般的应用系统,读写比例在10:1左右,而且插入操作和一般的更新操作很少出现性能问题,遇到最多的,也是最容易出问题的,还是一些复杂的查询操作,所以查询语句的优化显然是重中之重. 在数据 ...
- 爬虫入门系列(三):用 requests 构建知乎 API
爬虫入门系列目录: 爬虫入门系列(一):快速理解HTTP协议 爬虫入门系列(二):优雅的HTTP库requests 爬虫入门系列(三):用 requests 构建知乎 API 在爬虫系列文章 优雅的H ...