文章目录

  • 一、CTE特性
  • 1.CTE的优点
  • 2.CTE的使用场景
  • 3.CTE的语法
  • 二、SQL递归树状结构Demo
  • 1.创建表格
  • 2.使用SQL递归-依据父节点、查找所有子节点
  • 3.使用SQL递归-依据子节点查找所有父节点


一、CTE特性

从SQL Server 2005开始,提供了CTE(Common Table Expression,公用表表达式) 的语法支持。
CTE是定义在SELECT、INSERT、UPDATE或DELETE语句中的临时命名的结果集,同时CTE也可以用在视图的定义中。
在CTE中可以包括对自身的引用,因此这种表达式也被称为递归CTE。

1.CTE的优点

公用表表达式提供的功能其实和视图差不多,但是它不像视图一样把SQL语句保存在我们的数据库里面。
微软官方给出的使用CTE的优势:

1.可以编写一个递归查询。
2.要使用一个类似视图的功能,但是又不想把这个查询SQL语句的定义保存到数据库中。
3.要引用一个返回数据的SQL语句多次,只需要定义一次。
使用CTE可以把复杂的SQL语句按照逻辑分成简单独立的几个公用表表达式(CTE),这样的最大优势就是能够提高SQL语句的可读性和可维护性。

总结就是,CTE主要可以用于树结构的递归和简化SQL语句,增加可读性和可维护性。

2.CTE的使用场景

由于业务需要,我们经常会写一些比较复杂的SQL语句,里面可能会包含很多的JOIN或子查询,要维护和理清这种N多个表的JOIN关系是一件非常头疼的事情,而使用CTE就可以使维护和理解复杂的SQL语句变得简单一些。
在开发的时候使用子查询,一般是这种情况:需要从一个复杂的子查询,甚至多级子查询嵌套。在这种情况下,在整个SQL语句里面,无论你是直接写SQL语句还是把这段SQL语句包装成子查询然后用别名来访问,当业务需求越来越变得复杂,你可能随时需要修改这个长且复杂的SQL语句段,而维护这种复杂的、可读性差的SQL语句简直是噩梦。
有了CTE只有,我们就可以使用CTE来定义一个SQL语句,并且为这个SQL语句执行后返回的结果集定义一个别名,接下来就可以通过这个别名来引用这些预先执行返回的数据集,就像使用普通的表一样。

3.CTE的语法

一个公用表表达式主要包含三个主要部分:

1.CET名称(WITH后面,列名列之前)。
2.列名列(可选)。
3.CET查询语句主体(AS后面括起来的内容)。

二、SQL递归树状结构Demo

mysql 查询 树形菜单 sql查询树形结构_sqlserver

1.创建表格

CREATE TABLE category_Organization
(
	[ID] INT NOT NULL IDENTITY(1,1),--主键
    [GUID] INT NOT NULL,  --业务ID(唯一标识)
	[OrgCode] NVARCHAR(50) NULL, --机构编号
	[OrgName] NVARCHAR(50) NULL, --机构名称
	[OrgPGUID] NVARCHAR(50) NULL,--上级机构
	[ilevel] int null--级别
)
GO
 INSERT category_Organization VALUES(1,'a1','中国电信','0',1)
 INSERT category_Organization VALUES(2,'b1','中国电信陕西分公司','1',2)
 INSERT category_Organization VALUES(3,'c1','中国电信西安分公司','2',3)
 INSERT category_Organization VALUES(4,'d1','中国电信高新营业厅','3',4)
 INSERT category_Organization VALUES(5,'e1','高新营业客服部','4',5)
  INSERT category_Organization VALUES(6,'a2','中国移动','0',1)
 INSERT category_Organization VALUES(7,'b2','中国移动陕西分公司','6',2)
 INSERT category_Organization VALUES(8,'c2','中国移动西安分公司','7',3)
 INSERT category_Organization VALUES(9,'d2','中国移动高新营业厅','8',4)
 INSERT category_Organization VALUES(10,'e2','高新营业客服部','9',5)
SELECT *FROM category_Organization

mysql 查询 树形菜单 sql查询树形结构_SQL_02

2.使用SQL递归-依据父节点、查找所有子节点

放入存储过程中

CREATE PROCEDURE Child_ById
@id int --唯一标识
AS
BEGIN
with cte as
(
select category_Organization.GUID,OrgName,OrgPGUID from category_Organization where category_Organization.GUID=@id
union all
select a.GUID,a.OrgName,a.OrgPGUID from category_Organization a join cte b on a.OrgPGUID = b.GUID
)
select * from cte order by GUID asc
end
--EXEC Child_ById 1

mysql 查询 树形菜单 sql查询树形结构_cte_03

3.使用SQL递归-依据子节点查找所有父节点

CREATE PROC Parent_ById
@id int --唯一标识
AS
BEGIN
WITH CTE(GUID,OrgPGUID,OrgName,ilevel)
 AS
(
	SELECT GUID,OrgPGUID,OrgName,ilevel FROM category_Organization WHERE GUID=@id UNION ALL
	SELECT B.GUID,B.OrgPGUID,B.OrgName,B.ilevel FROM CTE A,category_Organization B WHERE A.OrgPGUID=B.GUID
)
SELECT GUID,OrgPGUID,OrgName,ilevel FROM CTE order by ilevel asc
end
--exec Parent_ById 10

mysql 查询 树形菜单 sql查询树形结构_SQL_04