sql server中的cte

本文涉及的产品
云数据库 RDS SQL Server,基础系列 2核4GB
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
简介: sql server中的cte从SQL Server 2005开始,提供了CTE(Common Table Expression,公用表表达式)的语法支持。CTE是定义在SELECT、INSERT、UPDATE或DELETE语句中的临时命名的结果集,同时CTE也可以用在视图的定义中。

sql server中的cte
从SQL Server 2005开始,提供了CTE(Common Table Expression,公用表表达式)的语法支持。

CTE是定义在SELECT、INSERT、UPDATE或DELETE语句中的临时命名的结果集,同时CTE也可以用在视图的定义中。

在CTE中可以包括对自身的引用,因此这种表达式也被称为递归CTE。

CTE的优点

公用表表达式提供的功能其实和视图差不多,但是它不像视图一样把SQL语句保存在我们的数据库里面。

微软官方给出的使用CTE的优势:

1.可以编写一个递归查询。

2.要使用一个类似视图的功能,但是又不想把这个查询SQL语句的定义保存到数据库中。

3.要引用一个返回数据的SQL语句多次,只需要定义一次。

使用CTE可以把复杂的SQL语句按照逻辑分成简单独立的几个公用表表达式(CTE),这样的最大优势就是能够提高SQL语句的可读性和可维护性。

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

CTE的使用场景

由于业务需要,我们经常会写一些比较复杂的SQL语句,里面可能会包含很多的JOIN或子查询,要维护和理清这种N多个表的JOIN关系是一件非常头疼的事情,而使用CTE就可以使维护和理解复杂的SQL语句变得简单一些。

在开发的时候使用子查询,一般是这种情况:需要从一个复杂的子查询,甚至多级子查询嵌套。在这种情况下,在整个SQL语句里面,无论你是直接写SQL语句还是把这段SQL语句包装成子查询然后用别名来访问,当业务需求越来越变得复杂,你可能随时需要修改这个长且复杂的SQL语句段,而维护这种复杂的、可读性差的SQL语句简直是噩梦。

有了CTE只有,我们就可以使用CTE来定义一个SQL语句,并且为这个SQL语句执行后返回的结果集定义一个别名,接下来就可以通过这个别名来引用这些预先执行返回的数据集,就像使用普通的表一样。

CTE的语法

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

1.CET名称(WITH后面,列名列之前)。

2.列名列(可选)。

3.CET查询语句主体(AS后面括起来的内容)。

with expression_name (column_name, …) as (

-- cte_query_definition cte查询语句定义

)
要注意的是,如果要定义多个表达式,需要用逗号分隔。

使用CTE进行多次查询

CTE是可以在跟随其后的查询中多次引用的。

with tmp(id) as (

select id from users where name like '杨%';

)
select * from tmp;
select * from orders where userId in (select id from tmp);
使用CTE递归查询树形记录(向上查询父节点或向下查询子节点)

CTE有一个特性就是它是支持递归的,即在CTE的查询语句主体中引用自身。这一特性常常被用在查询树形记录。

复制代码
with subqry(id, pid, name) as (

    select cb.id,
        cb.pid,
        cb.namefrom cb
    where cb.id = '001001001'

  

    union all

  

    select cb.id,
        cb.pid,
        cb.namefrom cb, subqry
    where cb.id = subqry.pid

)
select distinct *
from subqry
复制代码
复制代码
with subqry(id, pid, name) as (

    select cb.id,
        cb.pid,
        cb.name
    from cb
    where cb.id = '001'

  

    union all

  

    select cb.id,
        cb.pid,
        cb.name
    from cb, subqry
    where cb.pid = subqry.id

)
select distinct *
from subqry
复制代码
使用CTE的注意事项

1.CTE后面必须紧跟着使用CTE的SQL语句,比如SELECT、INSERT和UPDATE等,否则CTE将失效(直接报错)。

with tmp(id) as (

select id from users where favor = '牛奶';

)
select 1;
select * from tmp;
像上面的语句就会报【定义了公用表表达式,但没有使用】的错。

2.CTE后面也可以跟其他的CTE,但是只能使用一个WITH,多个CTE中间用逗号【,】隔开。

复制代码
with
milk(id) as (

select id from users where favor = '牛奶';

),
apple(id) as (

select id from users where favor = '苹果';

)
select id from milk, apple where milk.id = apple.id
复制代码
3.如果CTE表达式名称与某个实体表或者视图重名,则紧跟在该CTE后面的SQL语句使用的仍然是CTE。当然,后面再使用该同名就是使用实体表或视图了。

4.CTE可以引用自身,也可以引用在同一个WITH子句中预先定义的CTE,但是不允许前向引用(定义前使用)。

5.不能在CTE_QUERY_DEFINITION(CTE查询语句定义)中使用以下子句:

(1)COMPUTE或COMPUTE BY
(2)ORDER BY(除非指定了TOP 子句)
(3)INTO
(4)带有查询提示的OPTION 子句
(5)FOR XML
(6)FOR BROWSE

6.如果将CTE用于批处理的一部分的语句中,那么在它之前的语句必须以分号结尾。当然了,一个良好的习惯(技巧)是在写CTE的时候统统在WITH前加上分号【;】,这样就能避免出错。

复制代码
declare @id int
set @id = 0; -- 这里必须以分号结尾
;with tmp(name) as ( -- 在with前加上分号避免出错

select name from users where  unrequitedLove = '静静';

)
select * from tmp;
复制代码
总结

如果经常写查询的话,比如一些统计分析或制作报表,CTE是会经常使用到的,因为使用起来十分方便,也几乎不会有什么副作用,在一定程度上能够提高开发和维护的效率。另外,其递归属性在树形记录的查询中的应用十分广泛,是一个要好好掌握的语法。

原文地址https://www.cnblogs.com/yanggb/p/11165276.html

相关实践学习
使用SQL语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情: https://www.aliyun.com/product/rds/sqlserver
相关文章
|
5月前
|
SQL IDE Java
Java连接SQL Server数据库的详细操作流程
Java连接SQL Server数据库的详细操作流程
|
2月前
|
关系型数据库 MySQL 网络安全
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
|
4月前
|
SQL 存储 监控
SQL Server的并行实施如何优化?
【7月更文挑战第23天】SQL Server的并行实施如何优化?
111 13
|
4月前
|
SQL
解锁 SQL Server 2022的时间序列数据功能
【7月更文挑战第14天】要解锁SQL Server 2022的时间序列数据功能,可使用`generate_series`函数生成整数序列,例如:`SELECT value FROM generate_series(1, 10)。此外,`date_bucket`函数能按指定间隔(如周)对日期时间值分组,这些工具结合窗口函数和其他时间日期函数,能高效处理和分析时间序列数据。更多信息请参考官方文档和技术资料。
|
4月前
|
SQL 存储 网络安全
关系数据库SQLserver 安装 SQL Server
【7月更文挑战第26天】
60 6
|
4月前
|
存储 SQL C++
对比 SQL Server中的VARCHAR(max) 与VARCHAR(n) 数据类型
【7月更文挑战7天】SQL Server 中的 VARCHAR(max) vs VARCHAR(n): - VARCHAR(n) 存储最多 n 个字符(1-8000),适合短文本。 - VARCHAR(max) 可存储约 21 亿个字符,适合大量文本。 - VARCHAR(n) 在处理小数据时性能更好,空间固定。 - VARCHAR(max) 对于大文本更合适,但可能影响性能。 - 选择取决于数据长度预期和业务需求。
371 1
|
3月前
|
SQL 安全 Java
驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立安全连接。错误:“The server selected protocol version TLS10 is not accepted by client
驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立安全连接。错误:“The server selected protocol version TLS10 is not accepted by client
470 0
|
4月前
|
SQL Oracle 关系型数据库
MySQL、SQL Server和Oracle数据库安装部署教程
数据库的安装部署教程因不同的数据库管理系统(DBMS)而异,以下将以MySQL、SQL Server和Oracle为例,分别概述其安装部署的基本步骤。请注意,由于软件版本和操作系统的不同,具体步骤可能会有所变化。
305 3
|
4月前
|
SQL 存储 安全
数据库数据恢复—SQL Server数据库出现逻辑错误的数据恢复案例
SQL Server数据库数据恢复环境: 某品牌服务器存储中有两组raid5磁盘阵列。操作系统层面跑着SQL Server数据库,SQL Server数据库存放在D盘分区中。 SQL Server数据库故障: 存放SQL Server数据库的D盘分区容量不足,管理员在E盘中生成了一个.ndf的文件并且将数据库路径指向E盘继续使用。数据库继续运行一段时间后出现故障并报错,连接失效,SqlServer数据库无法附加查询。管理员多次尝试恢复数据库数据但是没有成功。
|
4月前
|
SQL 存储 关系型数据库
关系型数据库SQL Server学习
【7月更文挑战第4天】
77 2

热门文章

最新文章