zoukankan      html  css  js  c++  java
  • SQL Server2005数据库查询中使用CTE【原】

    通用表表达式(CTEs)是SQL Server 2005的一项新功能。它们类似于alias(如在SELECT T1.* FROM MyTable T1中),不过功能更为强大。本质上,CTE是一个临时结果集,它仅仅存在于它发生的语句中。您可以在SELECT、INSERT、DELETE、UPDATE或CTEATE VIEW语句中建立一个CTE。CTE类似于派生表,但拥有几项优点。
    CTE的优点

        与派生表不同,CTE能够引用自己本身。如果您不必存储视图,您可以用一个CTE来代替它。在一个语句中,您还可以多次引用CTE。应用CTE,您可以通过一个派生栏对结果进行分组。

        之前,我曾写过有关原子和分子查询的文章。原子查询建立一个表,而分子查询建立在原子查询之上,提供清晰与重复利用。应用CTE也可以达到同样的目的。您可以将查询区域分割成可读的“块”,然后用这些块建立一个复杂的查询。执行递归查询是CTE最重要也是最强大的功能。

        建立CTE

        CTE通过关键字WITH建立,其模板为:
    WITH CTE_name[ (column_name [,...n] ) ] AS ( CTE_query_specification )

        如果在CTE定义中提到的栏名称是唯一的,那么您可以不必给它们命名。不过,您同样也可以对它们重新命名。

        下面的例子应用到SQL Server 2005中的AdventureWorks样本数据库。这个数据库被高度规格化,因此需要几个连接来集合与雇员有关的信息。视图简化了这一操作,但也收集了所有有关雇员的信息,而您可能仅仅需要其中一部分资料。

        AdventureWorks的雇员数据分布在几个表中;而且,雇员与经理被存储在同一个表中(HumanResources.Employee),而他们的姓名(及其它数据)则存储在Person.Contact表中,这使得这个问题更加复杂。

        首先,我们建立一个恢复雇员姓名的CTE。

    WITH cte_Employee AS ( SELECT e.EmployeeID, c.FirstName, c.MiddleName, c.LastName, e.Title AS JobTitle, c.Phone, e.ManagerID FROM HumanResources.EmployeeAS e INNER JOIN Person.ContactAS c ON c.ContactID = e.ContactID )

        然后,我们可从CTE中选择一栏或几栏,就像它是一个标准的表或视图。

        接着我们再进一步。我们需要雇员和他们经理的姓名,于是我们使用CTE两次,把它自身连接起来。下面是完整的查询代码:

    WITH cte_Employee AS ( SELECT e.EmployeeID, c.FirstName, c.MiddleName, c.LastName, e.Title AS JobTitle, c.Phone, e.ManagerID FROM HumanResources.EmployeeAS e INNER JOIN Person.ContactAS c ON c.ContactID = e.ContactID ) SELECT E.FirstName + ' ' E.LastName Employee, M.FirstName + ' ' M.LastName Manager FROM cte_Employee AS E LEFT OUTER JOIN cte_Employee AS M ON E.ManagerID = M.EmployeeID



        限制:不能在一个语句中建立两个CTE。

        总结

        CTE是SQL Server 2005的一项强大而灵活的功能。它使得SQL Server的可读性更强,更易于管理,降低了查询的复杂程度。如上所述,您可以在一个SQL Server语句中多次应用CTE。

    以上是网上找到的一点教程,但实际用起来还远远不止这些,下面有一个我写的例子,经过反复琢磨终于出炉了

     

    CODE

    /*

    --董广祥 脚本日期: 06/23/2009 18:19:17 */

    CREATE PROCEDURE [dbo].[masterialStat]
        @CName NVARCHAR(50),
        @modelType NVARCHAR(20),
        @StartDate SMALLDATETIME,
        @EndDate SMALLDATETIME
    AS
        WITH    tb0 ( CName, beginningStock, CurrentPeriodInput, CurrentPeriodOutput, termEndStock )
                  AS ( SELECT   vyg.CName,
                                SUM(amout)
                                - ISNULL(( SELECT   SUM(amount)
                                           FROM     vyGinYillOutDetail vyd --减去出库
                                           WHERE    vyd.outPutDateTime < @EndDate
                                                    AND vyg.CName = vyd.CName
                                         ), 0)
                                - ISNULL(( SELECT   SUM(amount)
                                           FROM     vRackScrap vr --减去报废
                                           WHERE    outPutDateTime < @EndDate
                                                    AND vyg.CName = vr.CName
                                         ), 0),
                                0,
                                0,
                                0
                       FROM     vyGinYillDetail vyg
                       WHERE    vyg.CName LIKE '%' + @CName + '%'
                                AND vyg.category LIKE '%' + @modelType + '%'
                                AND vyg.YillDate < @StartDate
                       GROUP BY vyg.CName
     --期初结存
                     ) ,
                tb2 ( CName, beginningStock, CurrentPeriodInput, CurrentPeriodOutput, termEndStock )
                  AS ( SELECT   CName,
                                0,
                                0,
                                0,
                                SUM(amout)
                                - ISNULL(( SELECT   SUM(amount)
                                           FROM     vyGinYillOutDetail vyg
                                           WHERE    vyg.outPutDateTime > @EndDate
                                                    AND vyg.CName = vyd.CName
                                         ), 0) --减去出库
                                - ISNULL(( SELECT   SUM(amount)
                                           FROM     vRackScrap vr
                                           WHERE    vr.outPutDateTime > @EndDate
                                                    AND vr.CName = vyd.CName
                                         ), 0) --减去报废
                       FROM     vyGinYillDetail vyd
                       WHERE    vyd.CName LIKE '%' + @CName + '%'
                                AND category LIKE '%' + @modelType + '%'
                                AND YillDate > @StartDate
                       GROUP BY CName --期末结存
                     ) ,
                tb3 ( CName, beginningStock, CurrentPeriodInput, CurrentPeriodOutput, termEndStock )
                  AS ( SELECT   CName,
                                0,
                                SUM(amout),
                                0,
                                0
                       FROM     vyGinYillDetail
                       WHERE    CName LIKE '%' + @CName + '%'
                                AND category LIKE '%' + @modelType + '%'
                                AND YillDate >= @StartDate
                                AND YillDate <= @EndDate
                       GROUP BY CName --本期入库
                     ) ,
                tb4 ( CName, beginningStock, CurrentPeriodInput, CurrentPeriodOutput, termEndStock )
                  AS ( SELECT   CName,
                                0,
                                0,
                                SUM(amount),
                                0
                       FROM     vyGinYillOutDetail
                       WHERE    CName LIKE '%' + @CName + '%'
                                AND category LIKE '%' + @modelType + '%'
                                AND outPutDateTime >= @StartDate
                                AND outPutDateTime <= @EndDate
                       GROUP BY CName --本期出库
                     ) ,
                tb5 ( CName, beginningStock, CurrentPeriodInput, CurrentPeriodOutput, termEndStock )
                  AS ( SELECT   ISNULL(tb0.CName, tb3.CName),
                                ISNULL(tb0.beginningStock, 0),
                                ISNULL(tb3.CurrentPeriodInput, 0),
                                0,
                                0
                       FROM     tb0
                                FULL JOIN tb3 ON tb0.CName = tb3.CName --填充期初结存,本期入库
                     ) ,
                tb6 ( CName, beginningStock, CurrentPeriodInput, CurrentPeriodOutput, termEndStock )
                  AS ( SELECT   ISNULL(tb5.CName, tb4.CName),
                                ISNULL(tb5.beginningStock, 0),
                                ISNULL(tb5.CurrentPeriodInput, 0),
                                ISNULL(tb4.CurrentPeriodOutput, 0),
                                0
                       FROM     tb5
                                FULL JOIN tb4 ON tb5.CName = tb4.CName
     --填充期初结存,本期入库,本期出库
                     ) ,
                tb7 ( CName, beginningStock, CurrentPeriodInput, CurrentPeriodOutput, termEndStock )
                  AS ( SELECT   ISNULL(tb6.CName, tb2.CName),
                                ISNULL(tb6.beginningStock, 0),
                                ISNULL(tb6.CurrentPeriodInput, 0),
                                ISNULL(tb6.CurrentPeriodOutput, 0),
                                ISNULL(tb2.termEndStock, 0)
                       FROM     tb6
                                FULL JOIN tb2 ON tb6.CName = tb2.CName
     --填充期初结存,本期入库,本期出库,期末结存
                     )
            SELECT  CName,
                    beginningStock,
                    CurrentPeriodInput,
                    CurrentPeriodOutput,
                    termEndStock,
                    ( beginningStock + CurrentPeriodInput - CurrentPeriodOutput
                      + termEndStock ) Stock
            FROM    tb7

    本例出自:http://www.cnblogs.com/myssh/archive/2009/06/24/1509896.html

  • 相关阅读:
    定义类或对象
    CSS 超出的文字显示省略号(单行、多行)
    获取Json对象的长度以及判断json对象是否为空
    第三次作业附加
    八皇后问题解题报告(dfs
    STL学习笔记(不定期更新)
    寒假作业之三
    寒假作业之二(2)
    寒假作业之二(1)
    第一篇随笔居然是总结耶
  • 原文地址:https://www.cnblogs.com/myssh/p/1509896.html
Copyright © 2011-2022 走看看