本文来自:http://blog.csdn.net/songjie521/article/details/3321030

 

通用表表达式(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通过关键字WITH建立,其模板为:

使用公用表表达式(CTE)WITH CTE_name[ (column_name [,...n] ) ]
使用公用表表达式(CTE)AS
使用公用表表达式(CTE)( CTE_query_specification )


以下为多个示例的使用:

使用公用表表达式(CTE)USE Northwind
使用公用表表达式(CTE)--结果列别名
使用公用表表达式(CTE)WITH c AS 
使用公用表表达式(CTE)(
使用公用表表达式(CTE)SELECT YEAR(orderdate) AS orderyear,customerid
使用公用表表达式(CTE)FROM Orders
使用公用表表达式(CTE))
使用公用表表达式(CTE)
使用公用表表达式(CTE)SELECT orderyear,COUNT(DISTINCT customerid)AS numCusts FROM c GROUP BY orderyear
使用公用表表达式(CTE)--使用参数
使用公用表表达式(CTE)DECLARE @empid AS INT 
使用公用表表达式(CTE)SET @empid=3
使用公用表表达式(CTE)WITH c AS 
使用公用表表达式(CTE)(
使用公用表表达式(CTE)SELECT YEAR(orderdate) AS orderyear,customerid
使用公用表表达式(CTE)FROM Orders
使用公用表表达式(CTE)WHERE employeeid=@empid
使用公用表表达式(CTE))
使用公用表表达式(CTE)SELECT orderyear,COUNT(DISTINCT customerid)AS numCusts FROM c GROUP BY orderyear
使用公用表表达式(CTE)
使用公用表表达式(CTE)
使用公用表表达式(CTE)--多CTE.不同于派生表,CTE不能被直接嵌套.即,你不能在一个CTE内定义另一个CTE.但是,你可以用一个WITH语句定义多个CTE.
使用公用表表达式(CTE)WITH c1 AS 
使用公用表表达式(CTE)(
使用公用表表达式(CTE)SELECT YEAR(orderdate) AS orderyear,customerid
使用公用表表达式(CTE)FROM Orders
使用公用表表达式(CTE)),
使用公用表表达式(CTE)c2 AS 
使用公用表表达式(CTE)(
使用公用表表达式(CTE)SELECT orderyear,COUNT(DISTINCT customerid)AS numcusts FROM c1 GROUP BY orderyear
使用公用表表达式(CTE))
使用公用表表达式(CTE)
使用公用表表达式(CTE)SELECT orderyear,numcusts FROM c2 WHERE numcusts>70
使用公用表表达式(CTE)
使用公用表表达式(CTE)
使用公用表表达式(CTE)--多引用: 相对于派生表,CTE的一个优势是你可以在外部查询中多次引用同一个CTE名称.
使用公用表表达式(CTE)WITH YearlyCount AS 
使用公用表表达式(CTE)(
使用公用表表达式(CTE)SELECT YEAR(orderdate) AS orderyear,COUNT(DISTINCT customerid)AS numcusts FROM orders GROUP BY YEAR(orderdate)
使用公用表表达式(CTE))
使用公用表表达式(CTE)
使用公用表表达式(CTE)SELECT cur.orderyear,cur.numcusts,prv.orderyear,prv.numcusts,Cur.numcusts-prv.numcusts
使用公用表表达式(CTE)FROM yearlyCount Cur LEFT JOIN YearlyCount Prv
使用公用表表达式(CTE)ON cur.Orderyear=Prv.orderyear+1
使用公用表表达式(CTE)
使用公用表表达式(CTE)--修改数据.可能通过CTE修改数据
使用公用表表达式(CTE)--建立测试表
使用公用表表达式(CTE)IF OBJECT_ID('CustomersDups')IS NOT NULL
使用公用表表达式(CTE)DROP TABLE CustomersDups
使用公用表表达式(CTE)
使用公用表表达式(CTE)WITH CrossCustomers AS 
使用公用表表达式(CTE)(
使用公用表表达式(CTE)SELECT 1 AS c,c1.* FROM customers AS c1,customers AS c2
使用公用表表达式(CTE))
使用公用表表达式(CTE)SELECT ROW_NUMBER()OVER(ORDER BY c)AS keycol,CustomerID,CompanyName,ContactName,ContactTitle,Address,City,
使用公用表表达式(CTE)Region,PostalCode,Country,Phone,Fax    
使用公用表表达式(CTE)INTO customerdups 
使用公用表表达式(CTE)FROM CrossCustomers 
使用公用表表达式(CTE)
使用公用表表达式(CTE)SELECT * FROM customerdups
使用公用表表达式(CTE)
使用公用表表达式(CTE)CREATE UNIQUE INDEX index_idx_customerid_keycol
使用公用表表达式(CTE)ON customerdups (customerid,keycol)
使用公用表表达式(CTE)
使用公用表表达式(CTE)--以下删除重复的数据. 
使用公用表表达式(CTE)WITH JustDups AS 
使用公用表表达式(CTE)(
使用公用表表达式(CTE)--此查询语句不能得到对应的重复数据SELECT * FROM customerdups AS c1 WHERE keycol<(SELECT MAX(keycol) FROM customerdups AS c2 WHERE c2.customerid=c1.customerid)
    select * from customerdups as c1 where keycol in (select max(keycol) from customerdups as c2 group by col1.col2...)
使用公用表表达式(CTE))
使用公用表表达式(CTE)DELETE FROM justdups
使用公用表表达式(CTE)
使用公用表表达式(CTE)--容器对象,CTE可以用于诸如视图或内联UDF这样的容器中.这种能力允许实现封装.要熟练掌握.
使用公用表表达式(CTE)--视图
使用公用表表达式(CTE)CREATE VIEW dbo.vYearCnt
使用公用表表达式(CTE)AS 
使用公用表表达式(CTE)WITH YearCnt AS 
使用公用表表达式(CTE)(
使用公用表表达式(CTE)SELECT YEAR(orderdate) AS orderyear,COUNT(DISTINCT customerid)AS numCusts FROM Orders GROUP BY YEAR(orderdate)
使用公用表表达式(CTE))
使用公用表表达式(CTE)SELECT * FROM YearCnt
使用公用表表达式(CTE)GO 
使用公用表表达式(CTE)
使用公用表表达式(CTE)SELECT * FROM vYearCnt
使用公用表表达式(CTE)
使用公用表表达式(CTE)--UDF,可传递一个输入参数
使用公用表表达式(CTE)CREATE FUNCTION dbo.ufn_EmpYearCnt(@EmpID AS INT) RETURNS TABLE   
使用公用表表达式(CTE)AS   
使用公用表表达式(CTE)RETURN   
使用公用表表达式(CTE)  WITH EmpYearCnt AS   
使用公用表表达式(CTE)  (  
使用公用表表达式(CTE)    SELECT YEAR(OrderDate) AS OrderYear,  
使用公用表表达式(CTE)     COUNT(DISTINCT CustomerID) AS NumCusts  
使用公用表表达式(CTE)     FROM dbo.Orders  
使用公用表表达式(CTE)     WHERE EmployeeID=@EmpID  
使用公用表表达式(CTE)     GROUP BY YEAR(OrderDate)  
使用公用表表达式(CTE)  )  
使用公用表表达式(CTE)  SELECT * FROM EmpYearCnt;
使用公用表表达式(CTE)
使用公用表表达式(CTE)SELECT * FROM ufn_EmpYearCnt(2)
使用公用表表达式(CTE)
使用公用表表达式(CTE)--递归CTE,是SQL 2005中最重要的TSQL增强之一。通过纯基于集合的查询实现了递归查询。
DROP INDEX employees.idx_mgr_emp_ifname_ilname

 

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

相关文章: