SQL Server中怎么利用公用表表达式实现递归
发表于:2025-11-07 作者:千家信息网编辑
千家信息网最后更新 2025年11月07日,这篇文章给大家介绍SQL Server中怎么利用公用表表达式实现递归,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。公用表表达式简介:公用表表达式 (CTE) 可以认为是在单个 S
千家信息网最后更新 2025年11月07日SQL Server中怎么利用公用表表达式实现递归
这篇文章给大家介绍SQL Server中怎么利用公用表表达式实现递归,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。
公用表表达式简介:
公用表表达式 (CTE) 可以认为是在单个 SELECT、INSERT、UPDATE、DELETE 或 CREATE VIEW 语句的执行范围内定义的临时结果集。CTE 与派生表类似,具体表现在不存储为对象,并且只在查询期间有效。与派生表的不同之处在于,公用表表达式 (CTE) 具有一个重要的优点,那就是能够引用其自身,从而创建递归 CTE。递归 CTE 是一个重复执行初始 CTE 以返回数据子集直到获取完整结果集的公用表表达式。
下面先创建一个表,并插入一些数据:
create table Role_CTE( Id int not null, Name nvarchar(32) not null, ParentId int not null )insert into Role_CTE(Id,Name,ParentId)select '1','超级管理员','0' union select '2','管理员A','1' union select '3','管理员B','2' union select '4','会员AA','2' union select '5','会员AB','2' union select '6','会员BA','3' union select '7','会员BB','3' union select '8','用户AAA','4' union select '9','用户BBA','7' -- 创建一个复合聚集索引create clustered index Clu_Role_CTE_Indexon Role_CTE(Id,ParentId)with( pad_index=on, fillfactor=50, drop_existing=off, statistics_norecompute=on)select * from Role_CTE
查找指定节点的所有子孙节点:
使用普通 sql 语句实现:
declare @level intdeclare @node intdeclare @ResTab table( node int not null, lv int not null )set @level=0 -- 表示初始的等级set @node=3 --表示初始的节点ID,即从指定的哪个节点开始查找insert into @ResTab -- 为表变量插入初始的数据select Id,@level from Role_CTE where Id=@nodewhile(@@ROWCOUNT>0)begin set @level=@level+1 insert into @ResTab select b.Id,@level from @ResTab a join Role_CTE b on a.node=b.ParentId and lv=@level-1 -- join 等于 inner join(内连接)和自连接endselect a.node,b.Name,a.lv from @ResTab a left join Role_CTE b on a.node=b.Id
以上是根据指定节点ID(3),查找父节点ID(即字段 ParentId)等于指定的节点ID,如果有就插入,并继续循环。
PS:lv=@level-1 是重点,不然会进入死循环,作用就是限制只插入一次。
如果需要限制循环的次数,即递归的层数,那么只需要在 while 条件里面添加一个限制即可。如下:
declare @level intdeclare @node intdeclare @num intdeclare @ResTab table( node int not null, lv int not null )set @level=0 -- 表示初始的等级set @node=3 --表示初始的节点ID,即从指定的哪个节点开始查找set @num=1 -- 指定递归层级,即循环的次数insert into @ResTab -- 为表变量插入初始的数据select Id,@level from Role_CTE where Id=@nodewhile(@@ROWCOUNT>0 and @level<@num)begin set @level=@level+1 insert into @ResTab select b.Id,@level from @ResTab a join Role_CTE b on a.node=b.ParentId and lv=@level-1 -- join 等于 inner join(内连接)和自连接endselect a.node,b.Name,a.lv from @ResTab a left join Role_CTE b on a.node=b.Id
当然,如果指定了循环次数,就可以不用 while 判断语句的 @@rowcount>0 了。
使用 SQL CTE 实现:
declare @node int set @node=3;with temp_cteas( select Id,Name,0 lv -- 查询出"根节点",即指定的起始节点 from Role_CTE where Id=@node union all select b.Id,b.Name,a.lv+1 from temp_cte a join Role_CTE b on a.Id=b.ParentId)select * from temp_cte
使用 CTE 控制递归的层数,与上面类似。如下:
declare @node int declare @num intset @node=3;set @num=1;with temp_cteas( select Id,Name,0 lv -- 查询出"根节点",即指定的起始节点 from Role_CTE where Id=@node union all select b.Id,b.Name,a.lv+1 from temp_cte a join Role_CTE b on a.Id=b.ParentId and a.lv<@num --控制递归层数)select * from temp_cte
查找指定节点的所有祖先节点:
使用普通 sql 语句实现:
declare @level intdeclare @node intdeclare @num intdeclare @ResTab table( node int not null, lv int not null )set @level=0 -- 表示初始的等级set @node=8 --表示初始的节点ID,即从指定的哪个节点开始查找set @num=2 -- 指定递归层级,即循环的次数while(@level<=@num and @node is not null) -- 如果为空就表示没有查到父级了begin insert into @ResTab select @node,@level set @level=@level+1 select @node=ParentId from Role_CTE where Id=@nodeendselect a.node,b.Name,a.lv from @ResTab a left join Role_CTE b on a.node=b.Id
使用 SQL CTE 实现:
declare @node int declare @num intset @node=8;set @num=2;with temp_cteas( select Id,Name,ParentId,0 lv -- 查询出"根节点",即指定的起始节点 from Role_CTE where Id=@node union all select b.Id,b.Name,b.ParentId,a.lv+1 from temp_cte a join Role_CTE b on a.ParentId=b.Id and a.lv < @num --控制递归层数)select * from temp_cte
关于SQL Server中怎么利用公用表表达式实现递归就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。
节点
递归
表达式
公用
循环
会员
数据
次数
语句
查询
等级
管理员
控制
管理
起始
限制
普通
内容
变量
就是
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
泉州综合服务管理软件开发
科学软件开发教程
数据库lol
网络安全和信息化协调处处长
桓台制造业管理软件开发公司
游戏软件开发软件技术
沂南互联网科技有限公司
村级工业园数据库规划
互联网 科技金融 发展
军地共建网络安全
琉璃日月服务器怎么选职业
斗罗封神服务器中的雷鸣阎狱藤
win8网络安全密钥
神经网络技术的特点
狗妹在微信区哪个服务器
实验4 数据库安全性管理
网络安全法心得体会2021
数据库或语句
备份数据库的文件名称
谷歌网络安全审查
泰安金融软件开发
社区网络安全隐患有哪些
和平精英延迟低的服务器
什么软件开发商最穷
伪装身份是网络技术攻击吗
佛山市聚盈互联网络科技有限公司
黄元飞 网络安全
湖南管理软件开发多少钱
内网网络安全现状自查
数据库源名称 dw