以下内容转自:http://wudataoge.blog.163.com/blog/static/80073886200961652022389/

一.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) CTE除了可以简化嵌套SQL语句外,还可以进行递归调用,关于这一部分的内容将在下一篇文章中介绍。

sql with as 用法-Z的更多相关文章

  1. SQL语句---nvl 用法

    SQL语句---nvl 用法   一NVL函数是一个空值转换函数 NVL(表达式1,表达式2) 如果表达式1为空值,NVL返回值为表达式2的值,否则返回表达式1的值. 该函数的目的是把一个空值(nul ...

  2. SQL 语句日期用法及函数

    SQL 语句日期用法及函数 --DAY().MONTH().YEAR()——返回指定日期的天数.月数.年数:select day(cl_s_time) as '日' from class  --返回天 ...

  3. SQL 中ROLLUP 用法

    SQL 中ROLLUP 用法 ROLLUP 运算符生成的结果集类似于 CUBE 运算符生成的结果集. 下面是 CUBE 和 ROLLUP 之间的具体区别: CUBE 生成的结果集显示了所选列中值的所有 ...

  4. 标准SQL语言的用法

    原文链接:http://www.ifyao.com/2015/05/18/%E6%A0%87%E5%87%86%E7%9A%84sql%E8%AF%AD%E8%A8%80%E4%BD%BF%E7%94 ...

  5. 9.mybatis动态SQL标签的用法

    mybatis动态SQL标签的用法   动态 SQL MyBatis 的强大特性之一便是它的动态 SQL.如果你有使用 JDBC 或其他类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句有多么 ...

  6. oracle数据库中sql%notfound的用法

    SQL%NOTFOUND 是一个布尔值.与最近的sql语句(update,insert,delete,select)发生交互,当最近的一条sql语句没有涉及任何行的时候,则返回true.否则返回fal ...

  7. PL/SQL 的一些用法

    变量的声明,赋值,打印(declare是pl/sql里面的用法 variable是sql*plus里面的用法,variable相当于一个sql*plus环境的全局变量,declare里定义的是pl/s ...

  8. 【Oracle】数据库中sql%notfound的用法

    SQL%NOTFOUND 是一个布尔值.与最近的sql语句(update,insert,delete,select)发生交互,当最近的一条sql语句没有涉及任何行的时候,则返回true.否则返回fal ...

  9. sql的游标用法举例(Cursor)

    sql的游标用法举例 ), ) Declare authors_cursor Cursor For Select Name,TrueName From Account Open authors_cur ...

随机推荐

  1. 利用GDI+在Winfrom绘制验证码

    string yzm: private void yangzhengma() { Bitmap bt = new Bitmap(70,22);//创建位图对象 Graphics gs = Graphi ...

  2. val(),text(),html()的区别

    <script type="text/javascript" src="js/jquery-1.8.3.min.js"></script> ...

  3. 《用TCP/IP进行网络互连》读书笔记

    <用TCP/IP进行网络互连>读书笔记   第2章,基本网络技术 网络通信分类:基于连接的通信(connection-oriented),基于非连接的通信(connectionless) ...

  4. 用Java实现栈结构

    栈是一种先进后出的数据结构,出栈入栈都是操作的栈顶元素,下面是利用Java语言实现的一个简单的栈结构 class MyStack{ private int size;//栈大小 private Obj ...

  5. ssm整合快速入门程序(一)

    整合基础说明 spring 是一个开放源代码的设计层面框架,他解决的是业务逻辑层和其他各层的松耦合问题,因此它将面向接口的编程思想贯穿整个系统应用.Spring是于2003 年兴起的一个轻量级的Jav ...

  6. fitnesse - 安装部署

    fitnesse - 安装部署 2017-09-29 1 先决条件Java环境 确保机器上装了java, java -version 2 安装fitnesse http://fitnesse.org/ ...

  7. 解决将龙邱oled库移植到野火工程里,oled汉字无法显示问题

    第一,检查oled是否和单片机控制引脚正确相连. GND VCC CLK:时钟信号 miso RST: DC:DATE COMMAND/CONTROL CS:CHIP SELECT 第二,检查工程里是 ...

  8. Hybrid App混合模式开发的了解

    Hybrid App(混合模式移动应用)是指介于web-app.native-app这两者之间的app,兼具"Native App良好用户交互体验的优势"和"Web Ap ...

  9. 关于eclipse新建项目问题

    新建Dynamic Web Project项目的时候不能有中文名和空格. 不然会报错:The requested resource is not available. 里面的文件名也不能有中文名和空格 ...

  10. 一步步教你开发、部署第一个去中心化应用(Dapp) - 宠物商店

    今天我们来编写一个完整的去中心化(区块链)应用(Dapps), 本文可以和编写智能合约结合起来看. 写在前面 阅读本文前,你应该对以太坊.智能合约有所了解,如果你还不了解,建议你先看以太坊是什么除此之 ...