`
357029540
  • 浏览: 726369 次
  • 性别: Icon_minigender_1
  • 来自: 重庆
社区版块
存档分类
最新评论

SQLSERVER with的用法

阅读更多
以下内容转自: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)
分享到:
评论

相关推荐

    SQL Server 中 RAISERROR 的用法详细介绍

    SQL Server 中 RAISERROR 的用法 raiserror 的作用: raiserror 是用于抛出一个错误。[ 以下资料来源于sql server 2005的帮助 ] 其语法如下: RAISERROR ( { msg_id | msg_str | @local_variable } { ,severity ...

    SQL中Truncate的用法

    下面介绍SQL中Truncate的用法 当你不再需要该表时, 用 drop;当你仍要保留该表,但要删除所有记录时, 用 truncate;当你要删除部分记录时(always with a WHERE clause), 用 delete. Truncate是一个能够快速清空...

    UNIDAC 6.4.16 XE8

    SQLServer data provider Bug with WITH clause in TUniScript is fixed Bug with inserting identity fields through TUniLoader in the Direct mode is fixed Bug with updating a field containing a space in an...

    SQL语句中Group BY 和Rollup以及cube用法.txt

    SQL Server中的用法为group by colomn with [rollup|cube],首先要弄明白rollup 和cube,就要知道group by的用法,group by 为对列进行分组,只展现分组统计的值,而 rollup 为分层次展现,cube 为展现列中所有层次...

    将DataTable作为存储过程参数的用法实例详解

    最近工作中写了几个存储过程,需要向存储过程中传递字符串,因为SQL Server 2000中... 示例代码下载 一、测试环境 1、Windows Server 2008 R2 DataCenter 2、Visual Studio 2008 Team System With SP1 3、SQL Server 20

    经典SQL语句大全

    在SQLServer中分组时:不能以text,ntext,image类型的字段作为分组依据 在selecte统计函数中的字段,不能和普通的字段放在一起; 13、对数据库进行操作: 分离数据库: sp_detach_db; 附加数据库:sp_attach_db 后...

    程序员的SQL金典.rar

     本书特色:主要介绍SQL的语法规则及在实际开发中的应用,并且对SQL在MySQL、MS SQL Server、Oracle和DB2中的差异进行了分析;详细讲解数据库对增、删、改、查等SQL的支持并给出了相应的SQL应用案例;透彻分析函数...

    程序员的SQL金典4-8

     10.4.2 MS SQL Server中的自动增长字段  10.4.3 Oracle中的自动增长字段  10.4.4 DB2中的自动增长字段  10.5 业务主键与逻辑主键  10.6 NULL的学问  10.6.1 NULL与比较运算符  10.6.2 NULL和计算字段  ...

    sql-source-control:用于将SQL放入源代码控制系统的简单CLI

    安装npm install -g sql-source-control用法命令是特定于目录的,因此请在要创建脚本的目录中运行所有命令。 ssc --help 注意:确保在“ SQL Server网络配置”设置( )中启用TCP / IP。 如果未启用TCP / IP,您可能...

    程序员的SQL金典6-8

     10.4.2 MS SQL Server中的自动增长字段  10.4.3 Oracle中的自动增长字段  10.4.4 DB2中的自动增长字段  10.5 业务主键与逻辑主键  10.6 NULL的学问  10.6.1 NULL与比较运算符  10.6.2 NULL和计算字段  ...

    程序员的SQL金典7-8

     10.4.2 MS SQL Server中的自动增长字段  10.4.3 Oracle中的自动增长字段  10.4.4 DB2中的自动增长字段  10.5 业务主键与逻辑主键  10.6 NULL的学问  10.6.1 NULL与比较运算符  10.6.2 NULL和计算字段  ...

    程序员的SQL金典3-8

     10.4.2 MS SQL Server中的自动增长字段  10.4.3 Oracle中的自动增长字段  10.4.4 DB2中的自动增长字段  10.5 业务主键与逻辑主键  10.6 NULL的学问  10.6.1 NULL与比较运算符  10.6.2 NULL和计算字段  ...

    sql经典语句一部分

    在SQLServer中分组时:不能以text,ntext,image类型的字段作为分组依据 在selecte统计函数中的字段,不能和普通的字段放在一起; 13、对数据库进行操作: 分离数据库: sp_detach_db; 附加数据库:sp_attach_db 后...

    数据库操作语句大全(sql)

    在SQLServer中分组时:不能以text,ntext,image类型的字段作为分组依据 在selecte统计函数中的字段,不能和普通的字段放在一起; 13、对数据库进行操作: 分离数据库: sp_detach_db; 附加数据库:sp_attach_db ...

    数据库原理实验报告整合

    1、从“开始”菜单选择“所有程序”→“Microsoft SQL Server ”,打开“SQL Server Management Studio”窗口,使用Windows或SQL Server身份验证建立连接。 2、在“对象资源管理器”窗格中展开服务器,选择“数据库...

    db-doc::memo:一款生成在线数据库文档的小工具

    SQL Server Postgre SQL :alembic: 用法 下载 解压后双击打开DbDoc, 按照提示输入操作即可 ? Database type: 1:MySQL 2:SQL Server 1 ? Database host (127.0.0.1) : 127.0.0.1 ? Database port (3306) : 3306 ? ...

    FoodShala-Java:带有MySql Server的Java中的食品点餐系统

    Import the project in Eclipse IDE with GlassFish Server incorporated and click on RUN 特征 接受点菜 类别明智的展示菜肴。 餐馆老板仪表板。 用户购物车,结帐和付款页面。 登录并注册餐厅所有者和客户。 ...

    5分钟了解MySQL5.7中union all用法的黑科技

    union all在MySQL5.6下的表现 Part1:MySQL5.6.25 [root@HE1 ~]# MySQL -uroot -...Server version: 5.6.25-log MySQL Community Server (GPL) Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights re

    asp.net知识库

    在Framework1.0下同时连接SqlServer和Oracle的一些体会 XML XPath XPath最通俗的教程(ZZ) XPath中相对路径和绝对路径 XPath 简单语法 Asp.Net(C#)利用XPath解析XML文档示例 XSL .Net框架下的XSLT转换技术简介 一个...

    韩顺平oracle学习笔记

    2.最好学习过一门别的数据库(sql server,mysql , access) 教程推荐:oracle使用教程, 深入浅出oracle 记住:欲速则不达,做任何事情要遵循他的规律,循序渐进,信心很重要 成为一个oracle高手过程:理解小知识点-&gt;...

Global site tag (gtag.js) - Google Analytics