在实际运用中经常会创建这样的结构表Category(Id, ParentId, Name),
特别是用于树形结构时(菜单树,权限树..),
这种表设计自然而然地会用到递归,
若是在程序中进行递归(虽然在程序中递归真的更方便一些),
无论是通过ADO.NET简单sql查找还是ORM属性关联都会执行多次sql语句,
难免会造成一些性能上的损耗,所以干脆使用sql的函数来解决这个问题,用函数返回我们最终需要的结果。

数据准备

CREATE TABLE Region
(
Id INT IDENTITY PRIMARY KEY,
Name NVARCHAR(20),
ParentId INT
);
GO insert into Region(Name,ParentId) values('广东',NULL)
insert into Region(Name,ParentId) values('深圳',1)
insert into Region(Name,ParentId) values('惠州',2)
insert into Region(Name,ParentId) values('罗湖区',2)
insert into Region(Name,ParentId) values('福田区',2)
insert into Region(Name,ParentId) values('龙岗区',2)
insert into Region(Name,ParentId) values('惠阳区',3)
insert into Region(Name,ParentId) values('龙门县',3)
insert into Region(Name,ParentId) values('华强北',5)
insert into Region(Name,ParentId) values('体育馆',5) SELECT * FROM dbo.Region AS R

1.查询父节点的所有子节点

/*
* summary:递归获取所有子节点
*/
CREATE function GetRecursiveChildren
(
@Id int
)
returns @t table(Id int,ParentId int,Name nvarchar(20), [Level] int)
begin
declare @i int
set @i = 1
--根节点,Level = 0
insert into @t select @Id,@id,(select Name from Region where Id = @id),0
--直属子节点,Level = 1
insert into @t select Id,ParentId,Name,@i from Region where ParentId = @Id --如果没有新的值插入,循环结束
while @@rowcount<>0
begin
set @i = @i + 1;
insert into @t
select
a.Id,a.ParentId,a.Name,@i
from
Region a, @t b
where
a.ParentId = b.Id and b.Level = @i - 1
end
return
end
go
--调用函数
select * from GetRecursiveChildren(3)

--CTE(公用表表达式)实现
declare @id int
set @id = 3
;with t as--如果CTE前面有语句,需要用分号隔断
(
select Id, ParentId, Name
from Region
where Id = @id
union all
select r1.Id,r1.ParentId,r1.Name
from Region r1 join t as r2 on r1.ParentId = r2.Id
)
select * from t order by Id

2.根据子节点追溯根节点

create function GetRecursiveParent
(
@Id int
)
returns @t table(Id int,ParentId int,Name nvarchar(20), [Level] int)
as
begin
declare @i int
set @i = 1
--插入末节点,Level = 0
insert into @t select @Id,@id,(select Name from Region where Id = @id),0
--插入末节点的父节点,Level = 1
insert into @t select Id,ParentId,Name,@i from Region
where Id = (select ParentId from Region where Id = @Id)
--如果没有新的值插入,循环结束
while @@rowcount<>0
begin
set @i = @i + 1;
insert into @t
select
a.Id,a.ParentId,a.Name,@i
from
Region a, @t b
where
a.Id = b.ParentId and b.Level = @i - 1
end
return
end
go
--调用函数
select * from GetRecursiveParent(8)
go

3.根据导航数据查询节点

create function GetLevel
(
@Id int
)
returns @level table(IdLevel varchar(100),NameLevel nvarchar(200))
as
begin
declare @IdLevel varchar(100),@NameLevel nvarchar(200),@Name nvarchar(50)
select @IdLevel = cast(@Id as varchar(10))
select @NameLevel = (select Name from Region where Id = @Id) while(exists(select Id,ParentId from Region where Id = (select ParentId from Region where Id = @Id)))
begin
select @Id = Id,@Name = Name from Region where Id = (select ParentId from Region where Id = @Id)
select @IdLevel = cast(@Id as varchar(10)) + '>' + @IdLevel
select @NameLevel = @Name + '>' + @NameLevel
end
insert into @level select @IdLevel,@NameLevel
return
end
go
--调用函数
select * from GetLevel(10)
go

sql父子表结构,常用脚本的更多相关文章

  1. SQL server 表结构转Oracle SQL脚本

    SQL server 表结构转Oracle SQL脚本 /****** Object: StoredProcedure [dbo].[getOracle] Script Date: 2019/7/25 ...

  2. MS SQL 日常维护管理常用脚本(二)

    监控数据库运行 下面是整理.收集监控数据库运行的一些常用脚本,也是MS SQL 日常维护管理常用脚本(一)的续集,欢迎大家补充.提意见. 查看数据库登录名信息   Code Snippet SELEC ...

  3. SQL Server 一句Sql把表结构全部查询出来

    --一句Sql把表结构全部查询出来 SELECT 表名 = Case When A.colorder=1 Then D.name Else '' End, 表说明 = Case When A.colo ...

  4. sql复制表结构,复制表内容语句

    sql复制表结构,复制表内容语句 select * into b from a where 1<>1 select top 0 * into b from a insert into a ...

  5. 用户中心mysql数据库表结构的脚本

    /* Navicat MySQL Data Transfer Source Server : rm-m5e3xn7k26i026e75o.mysql.rds.aliyuncs.com Source S ...

  6. DB2表结构DDL脚本导出

    db2look是导出DDL语句脚本的命令,以下是对db2look的一个简单介绍. 语法:db2look -d <数据库名> -e -t <表名> -o <文件名>. ...

  7. sql复制表结构及复制表数据

    一.复制表结构 假设我们有一个数据表Person,有Id,FirstName,LastName,Weight,Height5个列,表结构可以参考这一篇.现在我们想创建一个新表叫People,表结构和P ...

  8. sql 查看表结构

    sqlserver 查看表结构 exec sp_help @TableName --得到表信息.字段,索引.constraint. exec sp_pkeys @TableName --得到主键. e ...

  9. 7.使用EXPLAIN 来分析SQL和表结构_1

    explain:查看执行计划 使用explain 关键字可以模拟优化器执行SQL查询语句,从而知道MySQL是如何处理你的SQL语句的 分析你的查询语句或是表结构的性能瓶颈 使用explain 可以获 ...

随机推荐

  1. 远离go path,弃用go get,使用go mod 进行go语言的学习

    标题说的是go语言的学习,因为我也没做过开发 文章要解决的仅仅是一个问题 当你使用go get 无论如何get不到所需的包的问题 第一步就是下载goland 新手极其推荐goland,因为直接使用gl ...

  2. ADRC-active disturbance rejection control-自抗扰控制器

    ADRC自抗扰控制基本思想要点: 1.标准型与总扰动,扩张状态与扰动整体辨识,微分信号生成与安排过渡过程以及扰动的消减与控制量产生. ADRC主要构成: 1)跟踪微分器(TD)---the track ...

  3. python学习day21 面向对象(三)嵌套/特殊方法

    1.嵌套 类/方法/对象都可以当做变量或嵌套到其他类型中. 函数的参数可以是任意类型. 可哈希(不可变)数据类型可以做字典的key. 类和对象可以做字典的key. 2.特殊方法(8) __init__ ...

  4. JavaScript开发中常用的代码规范配置文件

    一.jsconfig.json { compilerOptions: { target: 'es6', experimentalDecorators: true, allowSyntheticDefa ...

  5. 主成分分析_PCA解释

    粘贴自:http://blog.codinglabs.org/articles/pca-tutorial.html 数据的向量表示及降维问题 向量的表示及基变换 协方差矩阵及优化目标 协方差矩阵对角化 ...

  6. php5.4、5.5、5.6高版本中htmlspecialchars兼容性处理

    在使用php5.4以上版本以上时会有一个函数可能会报错 如下 Warning: htmlspecialchars(): charset `gbk' not supported, assuming ut ...

  7. MapReduce-CombineTextInputFormat 切片机制

    MapReduce 框架默认的 TextInputFormat 切片机制是对任务按文件规划切片,如果有大量小文件,就会产生大量的 MapTask,处理小文件效率非常低. CombineTextInpu ...

  8. jQuery使用():Callbacks回调函数列表之异步编程(含源码分析)

    Callbacks的基本功能回调函数缓存与调用 特定需求模式的Callbacks Callbacks的模拟源码 一.Callbacks的基本功能回调函数缓存与调用 Callbacks即回调函数集合,在 ...

  9. 075、配置Virtualbox backend(2019-04-22 周一)

    参考https://www.cnblogs.com/CloudMan6/p/7617211.html   Rex-Ray 支持多种backend,本节学习如何配置 virtualbox的backend ...

  10. Technocup 2019 - Elimination Round 1

    http://codeforces.com/contest/1030 B. Vasya and Cornfield 判断点是否在矩形内(包括边界) 把每条边转化为一个不等式 public static ...