一.WITH AS的含义 
    WITH AS短语,也叫做子查询部分(subquery factoring),可以让你做很多事情,定义一个SQL片断,该SQL片断会被整个SQL语句所用到。有的时候,是为了让SQL语句的可读性更高些,也有可能是在UNION ALL的不同部分,作为提供数据的部分。 
特别对于UNION ALL比较有用。因为UNION ALL的每个部分可能相同,但是如果每个部分都去执行一遍的话,则成本太高,所以可以使用WITH AS短语,则只要执行一遍即可。如果WITH AS短语所定义的表名被调用两次以上,则优化器会自动将WITH AS短语所获取的数据放入一个TEMP表里,如果只是被调用一次,则不会。而提示materialize则是强制将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
cr as
(
    select CountryRegionCode from person.CountryRegion where Name like 'C%'
)

select * from person.StateProvince where CountryRegionCode in (select * from cr)

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

在使用CTE时应注意如下几点:
1. CTE后面必须直接跟使用CTE的SQL语句(如select、insert、update等),否则,CTE将失效。如下面的SQL语句将无法正常使用CTE:

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

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。不允许前向引用。

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

(1)COMPUTE 或 COMPUTE BY

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

(3)INTO

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

(5)FOR XML

(6)FOR BROWSE

6. 如果将 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)

SQL中使用WITH AS提高性能-使用公用表表达式(CTE)简化嵌套SQL(转载)相关推荐

  1. 在Sql Server 2005使用公用表表达式CTE简化复杂的查询语句

    公用表表达式CTE是Sql Server 2005引入的一种新的表表达式.CTE在许多方面都类似于派生表.逻辑上CTE是一个临时结果集,它仅仅存在于它发生的语句中.您可以在SELECT.INSERT. ...

  2. SQL Server中公用表表达式 CTE 递归的生成帮助数据,以及递归的典型应用

    原文: SQL Server中公用表表达式 CTE 递归的生成帮助数据,以及递归的典型应用 本文出处:http://www.cnblogs.com/wy123/p/5960825.html 我们在做开 ...

  3. SQL中使用WITH AS提高性能-使用公用表表达式(CTE)简化嵌套SQL

    一.WITH AS的含义     WITH AS短语,也叫做子查询部分(subquery factoring),可以让你做很多事情,定义一个SQL片断,该SQL片断会被整个SQL语句所用到.有的时候, ...

  4. cte公用表表达式_在SQL Server中使用CTE进行插入和更新(公用表表达式)

    cte公用表表达式 In CTEs in SQL Server; Querying Common Table Expressions the first article of this series, ...

  5. as my sql 后面加表达式_SQL.WITH AS.公用表表达式(CTE)(转)

    一.WITH AS的含义 WITH AS短语,也叫做子查询部分(subquery factoring),可以让你做很多事情,定义一个SQL片断,该SQL片断会被整个SQL语句所用到.有的时候,是为了让 ...

  6. SQL语法练习 - 使用WITH AS提高性能简化嵌套SQL

    一.WITH AS的含义 WITH AS短语,也叫做子查询部分(subquery factoring),可以让你做很多事情,定义一个SQL片断,该SQL片断会 被整个SQL语句所用到.有的时候,是为了 ...

  7. 使用WITH AS提高性能简化嵌套SQL

    2019独角兽企业重金招聘Python工程师标准>>> 一.WITH AS的含义 WITH AS短语,也叫做子查询部分(subquery factoring),可以让你做很多事情,定 ...

  8. 了解JavaScript中的Memoization以提高性能,再看React的应用

    英文: Understanding Memoization in JavaScript to Improve Performance 中文: 了解JavaScript中的Memoization以提高性 ...

  9. cte公用表表达式_CTE SQL删除; 在SQL Server中删除具有公用表表达式的数据时的注意事项

    cte公用表表达式 In this article, the latest in our series on Common table expressions, we'll review CTE SQ ...

  10. 西欧文字入oracle,sql中的西欧字符到土耳其语(Western European Characterset to Turkish in sql)...

    sql中的西欧字符到土耳其语(Western European Characterset to Turkish in sql) 我遇到了严重的字符编码问题. 给出一些背景知识: 我有土耳其语的商业用户 ...

最新文章

  1. BZOJ4555[HEOI2016/TJOI2016]求和
  2. 从客户端检测到有潜在危险的Request.Form值的asp.net代码
  3. 【STM32】FreeRTOS任务挂起和恢复示例
  4. 第三次学JAVA再学不好就吃翔(part93)--LinkedHashMap
  5. python2卸载后yum不可用_centos7误删除python2导致的python和yum不可用处理-阿里云开发者社区...
  6. Speed Reading(POJ-3619 )
  7. python如何在函数中使用全局变量
  8. 2021-3-18全国个人所得税 完税证明开具 最新 其它经验都过时了,我北京网上打印
  9. oracle总结: INTERVAL DAY TO SECOND, 但却获得 NUMBER
  10. 【IDEA】IDEA修改项目名称
  11. excel如何打开100万行以上的csv文件
  12. H5组件Canvas画电子印章
  13. 【自然语言处理】3. NMT机器翻译案例实战(基于TensorFlow Addons Networks with Attention Mechanism)
  14. sudo apt-get install build-essential的作用
  15. 解决VM虚拟机导致硬盘灯常亮,很卡的问题 解决VM虚拟机导致硬盘灯常亮,很卡的问题
  16. C语言算数运算符顺序
  17. python_MOD13A3_NDVI 最大合成
  18. 江苏大学计算机专业江苏排名,江苏大学算名校吗?江苏大学排名为啥这么高?...
  19. Python自动化办公(一) :滴滴行程单信息提取存入excel表格 2021-04-13
  20. *srv.exe蠕虫病毒打开exe程序弹浏览器窗体的解决方案

热门文章

  1. 实验三十三、标准访问控制列表的配置
  2. linux用vim编辑后保存显示错误,因为vim编辑文档未保存。再次编辑同一个文件时出现报错的解决...
  3. HTML和CSS面试题
  4. RabbitMQ的六种工作模式(三)
  5. PHP生成海报 文字描边,如何使用css text-stroke属性来制作文字描边?(源代码)...
  6. java版本对应jdk版本_jdk版本对应数字
  7. android for循环比大小,如何让for()循环花费更少的时间(android)?
  8. LINUX下载编译:segment.jar/net.loomchild.segment.srx.Srx2SaxParser
  9. 研究了一下WORD的斜体,角度约20度
  10. 没想明白:JAVA的char是2字节,如何实现18030的4字节?