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

 

技术改变世界
原文地址:https://www.cnblogs.com/davidgu/p/2519356.html