SQL中 WITH AS 的使用方法

一.WITH AS的含义

WITH AS短语,也叫做子查询部分(subquery factoring),可以定义一个SQL片断,该SQL片断会被整个SQL语句用到。可以使SQL语句的可读性更高,也可以在UNION ALL的不同部分,作为提供数据的部分。

对于UNION ALL,使用WITH AS定义了一个UNION ALL语句,当该片断被调用2次以上,优化器会自动将该WITH AS短语所获取的数据放入一个Temp表中。而提示meterialize则是强制将WITH AS短语的数据放入一个全局临时表中。很多查询通过该方式都可以提高速度。

二.使用方法

先看下面一个嵌套的查询语句:

select * from person.StateProvince 
where CountryRegionCode in 
(select CountryRegionCode from person.CountryRegion 
where Name like 'C%'
)

上面的查询语句使用了一个子查询。虽然这条SQL语句并不复杂,但如果嵌套的层次过多,会使SQL语句非常难以阅读和维护。因此,也可以使用表变量的方式来解决这个问题,SQL语句如下:

declare @t table(CountryRegionCode nvarchar(3)) 
insert into @t(CountryRegionCode) 
(select CountryRegionCode from person.CountryRegion 
where Name like 'C%'
)select * from person.StateProvince 
where CountryRegionCode in (select * from @t)

虽然上面的SQL语句要比第一种方式更复杂,但却将子查询放在了表变量@t中,这样做将使SQL语句更容易维护,但又会带来另一个问题,就是性能的损失。

由于表变量实际上使用了临时表,从而增加了额外的I/O开销,因此,表变量的方式并不太适合数据量大且频繁查询的情况。

为此,在SQL Server 2005中提供了另外一种解决方案,这就是公用表表达式(CTE),使用CTE,可以使SQL语句的可维护性,同时,CTE要比表变量的效率高得多。

下面是CTE的语法:


[ WITH <common_table_expression> [ ,n ] ] 
<common_table_expression>::= 
expression_name [ ( column_name [ ,n ] ) ] 
AS 
( CTE_query_definition )
现在使用CTE来解决上面的问题,SQL语句如下:
with cte as 
( 
select CountryRegionCode from person.CountryRegion 
where Name like 'C%' 
)select * from person.StateProvince 
where CountryRegionCode in (select * from cte)

其中cte是一个公用表表达式,该表达式在使用上与表变量类似,只是SQL Server 2005在处理公用表表达式的方式上有所不同。

三. 语法注意

1

CTE后面必须直接跟使用CTE的SQL语句(如select、insert、update等),

否则,CTE将失效。如下面的SQL语句将无法正常使用CTE:

with cte as
(
select CountryRegionCode from person.CountryRegion 
where Name like 'C%'
)-- 加上这句会报错,应将这条SQL语句去掉
select * from person.CountryRegion -- 使用CTE的SQL语句应紧跟在相关的CTE后面 --
select * from person.StateProvince 
where CountryRegionCode in (select * from cte)

2

CTE后面也可以跟其他的CTE,

但只能使用一个with,多个CTE中间用逗号(,)分隔,如下面的SQL语句所示:

with cte1 as
(select * from table1 where name like 'abc%'
),
cte2 as
(select * from table2 where id > 20
),
cte3 as
(select * from table3 where price < 100
)
select a.* 
from cte1 a, cte2 b, cte3 c 
where a.id = b.id 
and a.id = c.id

3

如果CTE的表达式名称与某个数据表或视图重名,则紧跟在该CTE后面的SQL语句使用的仍然是CTE

当然,后面的SQL语句使用的就是数据表或视图了,如下面的SQL语句所示:

-- table1是一个实际存在的表
with table1 as
(select * from persons where age < 30
)
select * from table1 -- 使用了名为table1的公共表表达式
select * from table1 -- 使用了名为table1的数据表

4

CTE 可以引用自身

也可以引用在同一 WITH 子句中预先定义的 CTE。不允许前向引用。

--使用递归公用表表达式显示递归的多个级别
WITH DirectReports(ManagerID, EmployeeID, EmployeeLevel) AS 
(SELECT ManagerID, EmployeeID, 0 AS EmployeeLevelFROM HumanResources.EmployeeWHERE ManagerID IS NULLUNION ALLSELECT e.ManagerID, e.EmployeeID, EmployeeLevel + 1FROM HumanResources.Employee eINNER JOIN DirectReports dON e.ManagerID = d.EmployeeID 
)
SELECT ManagerID, EmployeeID, EmployeeLevel 
FROM DirectReports ;--使用递归公用表表达式显示递归的两个级别
WITH DirectReports(ManagerID, EmployeeID, EmployeeLevel) AS 
(SELECT ManagerID, EmployeeID, 0 AS EmployeeLevelFROM HumanResources.EmployeeWHERE ManagerID IS NULLUNION ALLSELECT e.ManagerID, e.EmployeeID, EmployeeLevel + 1FROM HumanResources.Employee eINNER JOIN DirectReports dON e.ManagerID = d.EmployeeID 
)
SELECT ManagerID, EmployeeID, EmployeeLevel 
FROM DirectReports 
WHERE EmployeeLevel <= 2 --使用递归公用表表达式显示层次列表
WITH DirectReports(Name, Title, EmployeeID, EmployeeLevel, Sort)
AS (SELECT CONVERT(varchar(255), c.FirstName + ' ' + c.LastName),e.Title,e.EmployeeID,1,CONVERT(varchar(255), c.FirstName + ' ' + c.LastName)FROM HumanResources.Employee AS eJOIN Person.Contact AS c ON e.ContactID = c.ContactID WHERE e.ManagerID IS NULLUNION ALLSELECT CONVERT(varchar(255), REPLICATE ('| ' , EmployeeLevel) +c.FirstName + ' ' + c.LastName),e.Title,e.EmployeeID,EmployeeLevel + 1,CONVERT (varchar(255), RTRIM(Sort) + '| ' + FirstName + ' ' + LastName)FROM HumanResources.Employee as eJOIN Person.Contact AS c ON e.ContactID = c.ContactIDJOIN DirectReports AS d ON e.ManagerID = d.EmployeeID)
SELECT EmployeeID, Name, Title, EmployeeLevel
FROM DirectReports 
ORDER BY Sort--使用 MAXRECURSION 取消一条语句
--可以使用 MAXRECURSION 来防止不合理的递归 CTE 进入无限循环。以下示例特意创建了一个无限循环,然后使用 MAXRECURSION 提示将递归级别限制为两级
WITH cte (EmployeeID, ManagerID, Title) as
(SELECT EmployeeID, ManagerID, TitleFROM HumanResources.EmployeeWHERE ManagerID IS NOT NULLUNION ALLSELECT cte.EmployeeID, cte.ManagerID, cte.TitleFROM cte JOIN  HumanResources.Employee AS e ON cte.ManagerID = e.EmployeeID
)
--Uses MAXRECURSION to limit the recursive levels to 2
SELECT EmployeeID, ManagerID, Title
FROM cte
OPTION (MAXRECURSION 2)
--在更正代码错误之后,就不再需要 MAXRECURSION。以下示例显示了更正后的代码
WITH cte (EmployeeID, ManagerID, Title)
AS
(SELECT EmployeeID, ManagerID, TitleFROM HumanResources.EmployeeWHERE ManagerID IS NOT NULLUNION ALLSELECT  e.EmployeeID, e.ManagerID, e.TitleFROM HumanResources.Employee AS eJOIN cte ON e.ManagerID = cte.EmployeeID
)
SELECT EmployeeID, ManagerID, Title
FROM cte

5

不能在 CTE_query_definition 中使用以下子句:

(1)COMPUTE 或 COMPUTE BY

(2)ORDER BY(除非指定了 TOP 子句)

(3)INTO

(4)带有查询提示的 OPTION 子句

(5)FOR XML

(6)FOR BROWSE

如果将 CTE 用在属于批处理的一部分的语句中,那么在它之前的语句必须以分号结尾,如下面的SQL所示:

declare @s nvarchar(3)
set @s = 'C%'
; -- 必须加分号
with
t_tree as
(
select CountryRegionCode from person.CountryRegion 
where Name like @s
)
select * from person.StateProvince 
where CountryRegionCode in (select * from t_tree)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/233123.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

你了解Redis中的跳跃表吗?

跳跃表的基本内容&#xff1a; 对于一个有序序列&#xff0c;链表相对于数组来说&#xff0c;删除和插入的效率要快很多&#xff0c;只需要改变指针的指向&#xff0c;但是在查找的时候&#xff0c;数组就要更占优势一些&#xff0c;可以随机访问&#xff0c;然而链表需要从头…

第51次中国互联网络发展状况统计报告

3月2日&#xff0c;中国互联网络信息中心&#xff08;CNNIC&#xff09;在京发布第51次《中国互联网络发展状况统计报告》&#xff08;以下简称&#xff1a;《报告》&#xff09;。《报告》显示&#xff0c;截至2022年12月&#xff0c;我国网民规模达10.67亿&#xff0c;较2021…

SGML .HTML 、XML和XHTML的区别?

SGML&#xff08;Standard Generalized Markup Language&#xff09;是一种标记语言的元语言&#xff0c;它定义了用于创建其他标记语言的规范。 HTML&#xff08;Hypertext Markup Language&#xff09;是基于SGML的标记语言&#xff0c;用于创建网页。 XML&#xff08;eXte…

oracle与gbase8s迁移数据类型对照

声明&#xff1a;以下为笔者阅读gbase官方文档和oracle官方文档的理解&#xff0c;如有错误&#xff0c;敬请指正。oracle与gbase8s迁移数据类型对照及举例说明 最终结论&#xff1a;oracle与gbase8s数据类型对应关系关于单精度与双精度的区别关于定点与浮点定义的区别精度的定…

动态规划 - 1137.第N个泰波那契数(C#和C实现)

动态规划 - 1137.第N个泰波那契数(C#和C实现) 题目描述 泰波那契序列 Tn 定义如下&#xff1a; T0 0, T1 1, T2 1&#xff0c;且在 n > 0 的条件下 Tn3 Tn Tn1 Tn2。给你整数 n&#xff0c;请返回第 n 个泰波那契数 Tn 的值。 示例 1: 输入&#xff1a;n 4 输出…

[报错已解决]得到一个不期待的值added_cond_kwargs,图生图和文生图的pipline是不同的

报错内容 得到一个不期待的值added_cond_kwargs 问题原因 对照下图&#xff0c;做测试unet_2d_condition.py里面UNet2dConditionModel类的forward输入 而StableDiffusionPipline&#xff08;文生图t2i&#xff09;的self.unet输入里面多了一个added_cond_kwargs需要写 从下图可…

函数torch.bincount( )的用法

torch.bincount()函数是PyTorch中的一个函数&#xff0c;用于计算一维整数张量中每个非负整数值出现的频次 函数的用法 &#xff1a; torch.bincount(input, weightsNone, minlength0) → Tensor 参数&#xff1a; input&#xff1a;输入的一维整数张量weights&#xff08;…

JsonNode、ObjectNode和ArrayNode

我个人不喜欢fastjson&#xff0c;但是项目中很多地方用到json字符串转换对象但又不想创建pojo 所以使用jackson的JsonNode、ObjectNode和ArrayNode就非常好用&#xff0c;万能对象&#xff0c;这三 个对象是非常全面的&#xff0c;感兴趣的可以看下源码 JsonNode 只读&#x…

机器学习——支持向量机

目录 一、基于最大间隔分隔数据 二、寻找最大间隔 1. 最大间隔 2. 拉格朗日乘子法 3. 对偶问题 三、SMO高效优化算法 四、软间隔 五、SMO算法实现 1. 简化版SMO算法 2. 完整版SMO算法 3. 可视化决策结果 六、核函数 1. 线性不可分——高维可分 2. 核函数 …

【大数据面试】MapReduce常见问题与答案

目录 介绍下MapReduce MapReduce优缺点 MapReduce架构 MapReduce工作原理 MapReduce哪个阶段最费时间 ✅MapReduce中的Combine是干嘛的?有什么好出? ✅MapReduce环形缓冲区是什么 ✅MapReduce为什么一定要有环型缓冲区 MapReduce为什么一定要有Shuffle过程 MapRedu…

Autosar通信实战系列08-Com模块相关开发问题总结

本文框架 前言1. Com模块重要接口回顾2. 如何让通过Com模块配置改善发送报文周期不准问题?3. UDS 0x28服务关闭或打开APP报文与Com模块的交互?4. 如何在Com层实现接收报文的超时,ARC及信号有效性监控?4.1 信号超时监控的配置4.2 报文ARC校验4.3 报文信号值有效性校验前言 …

linux命令绕过

WAF绕过命令执行 1 命令分隔符2 命令执行绕过2.1 绕过空格2.2 拼接2.3 编码2.4 单引号、双引号绕过2.5 反斜线绕过2.6 通配符绕过 1 命令分隔符 linux&#xff1a; && || & | ; # &&绕过 [rootlocalhost ~]# echo 123&& cat /etc/passwd 123 root:…

拾壹[11],缩放形状匹配,函数CreateScaledShapeModel/FindScaledShapeModel

函数CreateScaledShapeModel 函数功能 创建可缩放比例的形状匹配模板 C形式 LIntExport void CreateScaledShapeModel( const HObject& Template, const HTuple& NumLevels, const HTuple& AngleStart, const HTuple& AngleExtent, const HTuple& …

设计模式 原型模式 与 Spring 原型模式源码解析(包含Bean的创建过程)

原型模式 原型模式(Prototype模式)是指&#xff1a;用原型实例指定创建对象的种类&#xff0c;并且通过拷贝这些原型&#xff0c;创建新的对象。 原型模式是一种创建型设计模式&#xff0c;允许一个对象再创建另外一个可定制的对象&#xff0c;无需知道如何创建的细节。 工作原…

threejs 内置变量函数

参考glsl文档 threejs 内置变量 vertex shader highp vec4 gl_PointSize 点大小mediump float gl_Position 不用多说 fragment shader mediump vec4 gl_FragCoord 屏幕坐标系bool gl_FrontFacingmediump vec4 gl_FragColor 最重要的mediump vec4 gl_FragData[gl_MaxDrawBu…

新年跨年烟花超酷炫合集【内含十八个烟花酷炫效果源码】

❤️以下展示为全部烟花特效效果 ❤️下方仅展示部分代码 ❤️源码获取见文末 🎀HTML5烟花喷泉 <style> * {padding:0;margin:0; } html,body {positi

清华提出ViLa,揭秘 GPT-4V 在机器人视觉规划中的潜力

人类在面对简洁的语言指令时&#xff0c;可以根据上下文进行一连串的操作。对于“拿一罐可乐”的指令&#xff0c;若可乐近在眼前&#xff0c;下意识的反应会是迅速去拿&#xff1b;而当没看到可乐时&#xff0c;人们会主动去冰箱或储物柜中寻找。这种自适应的能力源于对场景的…

springboot的配置文件,以及spring boot自动装配的原理,bean的管理。

配置优先级&#xff1a; spring boot中自此三种格式的配置文件&#xff1a; server.port&#xff1a;8081 server.port&#xff1a;8082 server.port&#xff1a;8083 spring boot还支持两种外部配置&#xff1a; java系统属性&#x…

软件测试人才稀缺!揭秘为什么你找不到软件测试工作?

最近后台很多粉丝给我留言&#xff1a; 2023年软件测试已经崩盘了吗&#xff0c;为什么都找不到工作了&#xff1f; 确实&#xff0c;今年经济大环境不好&#xff0c;企业也都在降本增效&#xff0c;如果技术能力还在被应届生竞争岗位的阶段&#xff0c;只会越来越难。 找不…

【大数据面试】YARN常见问题与答案

目录 介绍下YARN YARN有几个模块 YARN工作机制 YARN有什么优势&#xff0c;能解决什么问题? YARN容错机制 YARN高可用 YARN调度器 YARN中Container是如何启动的? YARN的改进之处&#xff0c;Hadoop3.x相对于Hadoop 2.x? YARN监控 介绍下YARN YARN有几个模块 Yar…