在实际运用中经常会创建这样的结构表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. 数据库MySQL——安装

    MySQL 安装 Mysql安装: 1.通过二进制的方式安装 二进制安装方式中,包括rpm版本以及glibc版本. rpm版本就是在特定linux版本下编译的,如果你的linux版本匹配,就可以安装; ...

  2. jmeter笔记(9)--JDBC Request的使用

    JDBC Request可以向数据库发送一个JDBC(Java Data Base Connectivity)请求(sql语句),获取返回的数据库数据进行操作.它需要和JDBC Connection ...

  3. 项目经理的“时间管理法则”(内含10G项目管理书籍)

    项目经理特别是大型项目的项目经理往往琐事缠身,好象每件事情都很重要都需要处理,如何在“百事缠身”的环境下,管理和充分利用好自己的时间,是困扰项目经理的一个大问题.有人会问,为什么我努力善用每分每秒,却 ...

  4. 第一个thinkphp项目遇到的知识

    本文是于项目完成后所写,基本是想到 哪写到哪,所以顺序会很乱. 1.在后台处理ueditor这种文本编辑器的时候,会遇到取值问题,如果你想要取纯文本内容:getContentTxt(),没有段落格式: ...

  5. woe_iv原理和python代码建模

    python信用评分卡(附代码,博主录制) https://study.163.com/course/introduction.htm?courseId=1005214003&utm_camp ...

  6. Java基础--常见计算机编码类型

    计算机编码指电脑内部代表字母或数字的方式,常见的编码方式有:ASCII编码,GB2312编码(简体中文),GBK,BIG5编码(繁体中文),ANSI编码,Unicode,UTF-8编码等. 1.ASC ...

  7. vue引入fastclick设置输入框type="number"报错Failed to execute 'setSelectionRange' on 'HTMLInputElement': The input element's type ('number') does not support selection.的解决办法

    将输入框type设为text,通过正则验证输入的值

  8. HTML 重定向 页面跳转

    通过响应头重定向 响应状态 301 和 302 可以指定重定向URL, 推荐使用302 FOUND HttpServletResponse. static final int SC_MOVED_TEM ...

  9. VS注释快捷键

    注释:        先CTRL+K,然后CTRL+C 取消注释: 先CTRL+K,然后CTRL+U 代码自动对齐:1, ctrl+a 2, ctrl+k 3, ctrl+f

  10. react项目构建

    1.react脚手架 npm install -g create-react-app create-react-app myproject 2.页面配置(bootcdn) <script src ...