zoukankan      html  css  js  c++  java
  • 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

     

    技术改变世界
  • 相关阅读:
    Zboot权限后台管理系统开源啦
    java中的强引用,软引用,弱引用,虚引用
    基于Hexo搭建个人博客
    拾遗Timer定时器
    手把手教你使用jmeter接口测试
    Vue 常见的面试题
    vue脚手架环境搭建
    vue过滤器
    基础面试题总结1
    Promise 库 lie.js 源码解读
  • 原文地址:https://www.cnblogs.com/davidgu/p/2519356.html
Copyright © 2011-2022 走看看