SQL技巧(二) - CTE(公用表达式)初步接触

CTE - Common Table Expression(公用表达式)是SQL 2005最重要的改进之一。

子查询有时候使用起来嵌套很复杂, 而使用#tmp类似的临时表, 性能又比较差。

这个时候,介于两者之间的解决方案,CTE诞生了。

我们可以用它来替代临时表

在使用CTE时应注意如下几点:

1. CTE后面必须直接跟使用CTE的SQL语句(如select、insert、update等),否则,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。不允许前向引用

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语句外,还可以进行递归调用

 

闲话不多说, 来看看我亲自创建的一个查询的例子, 以AdventureWorks数据库为例

 

with BlueProducts(ProductID, Name, ProductNumber, Color)
as
(
    select ProductID, Name, ProductNumber, Color
    from Production.Product
    where Color='Blue'
),
PriceOrderDetail(UnitPriceSum, ProductID)
as
(
    select SUM(UnitPrice), ProductID
    from Sales.SalesOrderDetail
    group by ProductID
    having SUM(UnitPrice)>100000
)

select sod.ProductID, sod.SalesOrderID, BlueProducts.Name as ProductName, 
        BlueProducts.ProductNumber, BlueProducts.Color, sod.UnitPrice, po.UnitPriceSum
from Sales.SalesOrderDetail as sod inner join BlueProducts
    on sod.ProductID=BlueProducts.ProductID inner join PriceOrderDetail po
    on sod.ProductID=po.ProductID
order by po.UnitPriceSum

 

892 51084 HL Touring Frame - Blue, 54 FR-T98U-54 Blue 602.346 101726.2003
892 51106 HL Touring Frame - Blue, 54 FR-T98U-54 Blue 602.346 101726.2003

......

959 71918 Touring-3000 Blue, 58 BK-T18U-58 Blue 445.41 118367.7075
959 71894 Touring-3000 Blue, 58 BK-T18U-58 Blue 445.41 118367.7075

......

966 51126 Touring-1000 Blue, 46 BK-T79U-46 Blue 1382.7606 800403.8211
966 51131 Touring-1000 Blue, 46 BK-T79U-46 Blue 1311.2385 800403.8211

 

 

时间: 2024-09-15 01:46:38

SQL技巧(二) - CTE(公用表达式)初步接触的相关文章

Sql学习第三天——SQL 关于CTE(公用表达式)的递归查询使用_MsSql

关于使用CTE(公用表表达式)的递归查询----SQL Server 2005及以上版本 公用表表达式 (CTE) 具有一个重要的优点,那就是能够引用其自身,从而创建递归 CTE.递归 CTE 是一个重复执行初始 CTE 以返回数据子集直到获取完整结果集的公用表表达式. 当某个查询引用递归 CTE 时,它即被称为递归查询.递归查询通常用于返回分层数据,例如:显示某个组织图中的雇员或物料清单方案(其中父级产品有一个或多个组件,而那些组件可能还有子组件,或者是其他父级产品的组件)中的数据. 递归 C

SQL技巧(三) - CTE实战之代替临时表

一段复杂的逻辑,原先的代码我使用#tmp临时表来实现,性能是不好的,而且要考虑到多用户时的锁的问题 代码如下: declare @StartDate datetimedeclare @EndDate datetimeselect @StartDate='2012-09-28'select @EndDate='2012-10-03' if exists (select * from tempdb..sysobjects where name like '#tmpPolicyId%')    dro

关于使用CTE(公用表表达式)的递归查询

本文转载:http://www.cnblogs.com/shuangnet/archive/2013/03/22/2975929.html   公用表表达式 (CTE) 具有一个重要的优点,那就是能够引用其自身,从而创建递归 CTE.递归 CTE 是一个重复执行初始 CTE 以返回数据子集直到获取完整结果集的公用表表达式. 当某个查询引用递归 CTE 时,它即被称为递归查询.递归查询通常用于返回分层数据,例如:显示某个组织图中的雇员或物料清单方案(其中父级产品有一个或多个组件,而那些组件可能还有

SQL注入天书—ASP注入漏洞全接触

SQL注入天书-ASP注入漏洞全接触选择自 digituser 的 Blog 随着B/S模式应用开发的发展,使用这种模式编写应用程序的程序员也越来越多.但是由于这个行业的入门门槛不高,程序员的水平及经验也参差不齐,相当大一部分程序员在编写代码的时候,没有对用户输入数据的合法性进行判断,使应用程序存在安全隐患.用户可以提交一段数据库查询代码,根据程序返回的结果,获得某些他想得知的数据,这就是所谓的SQL Injection,即SQL注入. SQL注入是从正常的WWW端口访问,而且表面看起来跟一般的

SQL 转化LINQ 或 lambda表达式

问题描述 SQL转化LINQ或lambda表达式SELECTb.*FROM(SELECTappli_no,max(revision_no)ASrevision_noFROMTBAARS_COMMITTEE_APPLICATIONGROUPBYappli_no)aINNERJOINTBAARS_COMMITTEE_APPLICATIONbON(a.appli_no=b.appli_noANDa.revision_no=b.revision_no) 解决方案 解决方案二:varquery=fromx

初步接触maven,新建个项目后,run as-&amp;amp;gt;maven clean报错

问题描述 初步接触maven,新建个项目后,run as->maven clean报错 错误: 找不到或无法加载主类 $M2_HOME 但我环境变量都已经设置过M2_HOME,为什么会有这个错误 如果我在cmd环境下,运行是没有错误的 解决方案 IDE的maven环境没设置 解决方案二: eclipse-->run as --> maven test 中文乱码Maven clean报错---------------------- 解决方案三: 但我eclipse里面已经配置了额,而且还和

【Silverlight】Bing Maps开发应用与技巧二:自定义图钉标注控件和动态ToolPa

[Silverlight]Bing Maps开发应用与技巧二:自定义图钉标注控件和动态ToolPanel 在Bing Maps Silverlight Control中以及为我们提供了地图图钉控件Pushpin,我曾经在<使用图钉层(Pushpin layer)及地图图层(MapLayer)>一文中介绍过他的使用方法,本篇主要介绍如何自定义图钉标注控件以及对他的一些扩展,比如实现图钉的动态ToolPanel. 关于图钉的UI外观的设计这里就不详细介绍了,通过Blend可以快速的构建UI界面.首

使用Office2010截图、抠图技巧二:移除图片中的背景

技巧二:移除图片中的背景 对于已插入Word文档的图片,我们可以很方便的去除图片中的背景,这样就不需要动用庞大的photoshop,更妙的是还可以添加或去除水印. 选择图片,切换到"PictureTools"选项卡,可以在这里发现名为"BackgroundRemoval"的按钮,单击 "BackgroundRemoval"按钮,很快就可以把想要的图片抠出来,是不是很神奇?

pl/sql-用PL/SQL生成二维码并以图片形式存入数据库表中

问题描述 用PL/SQL生成二维码并以图片形式存入数据库表中 在数据库中创建一张表 -- Create table create table QRCode ( id varchar2(10), img blob ) tablespace USERS storage ( initial 64K minextents 1 maxextents unlimited ); 用PL/SQL生成二维码并以图片形式存入表QRCode的img字段中