1 CTE語法WITH關鍵字
通用表表示式(Common Table Express, CTE),將派生表定義在查詢的最前面。要使用CTE開始建立一個查詢,可以使用WITH關鍵字。
CTE語法:
WITH <expression_name> [(column_name [,...n])] AS ( CTE_query_definition) [, <another_expression>] <query>
首先為CTE提供一個名稱,該名稱類似於用於派生表的別名。然後可以提供CTE將返回的列名列表;如果CTE指定了它的所有返回列,則這是可選操作。最後,在圓括號中新增CTE查詢的定義,最後新增使用CTE的主查詢。
WITH關鍵字之前的語句必須使用分號(;)結束。
示例
WITH cte AS ( SELECT * FROM [dbo].[Product] ) SELECT [ProductID],[ProductCode],[ProductName],[UnitPrice] FROM cte
連線查詢示例
WITH ProductCTE([CategoryID], [ProductsCount]) AS ( SELECT [CategoryID],COUNT(1) FROM [dbo].[Product] GROUP BY [CategoryID] ) SELECT c.[CategoryID],c.[CategoryName], cte.[ProductsCount] FROM [dbo].[Category] c INNER JOIN ProductCTE cte ON c.[CategoryID] = cte.[CategoryID] ORDER BY cte.[ProductsCount]
2 使用多個CTE
使用WITH開始語句可以定義多個CTE,不需要重複使用WITH關鍵字,每一個CTE可以使用在該語句中已經定義的任意CTE(作為其定義的一部分)。
WITH CategoryCTE AS ( SELECT * FROM [dbo].[Category] ),ProductCTE AS ( SELECT p.*,cte.[CategoryName] FROM [dbo].[Product] p INNER JOIN CategoryCTE cte ON p.[CategoryID] = cte.[CategoryID] ) SELECT * FROM ProductCTE
3 遞迴CTE
遞迴公用表表示式是在CTE內的語句中呼叫其自身的CTE。
示例
WITH cte([CategoryID],[CategoryName],[ParentID],[Level]) AS ( -- 查詢語句 SELECT [CategoryID],[CategoryName],[ParentID],1 AS [Level] FROM [dbo].[Category] WHERE [ParentID] IS NULL UNION ALL -- 遞迴語句 SELECT c.[CategoryID],c.[CategoryName],c.[ParentID], cte.[Level] + 1 FROM [dbo].[Category] c INNER JOIN cte ON c.[CategoryID] = cte.[ParentID] ) SELECT [CategoryID],[CategoryName],[ParentID],[Level] FROM cte
限制遞迴層次
WITH cte([CategoryID],[CategoryName],[ParentID],[Level]) AS ( -- 查詢語句 SELECT [CategoryID],[CategoryName],[ParentID],1 AS [Level] FROM [dbo].[Category] WHERE [ParentID] IS NULL UNION ALL -- 遞迴語句 SELECT c.[CategoryID],c.[CategoryName],c.[ParentID], cte.[Level] + 1 FROM [dbo].[Category] c INNER JOIN cte ON c.[CategoryID] = cte.[ParentID] ) SELECT [CategoryID],[CategoryName],[ParentID],[Level] FROM cte OPTION(MAXRECURSION 2)
Where過濾遞迴結果資料層次
WITH cte([CategoryID],[CategoryName],[ParentID],[Level]) AS ( -- 查詢語句 SELECT [CategoryID],[CategoryName],[ParentID],1 FROM [dbo].[Category] WHERE [ParentID] IS NULL UNION ALL -- 遞迴語句 SELECT c.[CategoryID],c.[CategoryName],c.[ParentID], [Level] + 1 FROM [dbo].[Category] c INNER JOIN cte ON c.[CategoryID] = cte.[ParentID] ) SELECT [CategoryID],[CategoryName],[ParentID],[Level] FROM cte WHERE cte.[Level] <= 3