摘要:SQL - 使用 一般資料表運算式 CTE (Common Table Expression)
早期可以透過暫存資料表(# 或 ##)或者 table 來存放資料,現在也可以使用 一般資料表運算式 CTE (Common Table Expression) 來暫存資料。雖然 CTE 的查詢是使用 Select 查詢,但是依照 MSDN 的說明,仍有一些限制,那就是在 CTE 中不可以使用以下的子句:
1.COMPUTE 或 COMPUTE BY
2.ORDER BY (除非指定了 TOP 子句)
3.INTO
4.含有查詢提示的 OPTION 子句
5.FOR XML
6.FOR BROWSE
以下就來實作一些 CTE 的範例...
範例一:單一的 CTE 用法
WITH OrdersTable (訂單ID, 客戶ID, 員工ID) as
(
Select OrderID, CustomerID, EmployeeID
from dbo.Orders
)
Select *
From OrdersTable
範例二:兩個 CTE 作 Join
WITH OrdersTable (訂單ID, 客戶ID, 員工ID) as
(
Select OrderID, CustomerID, EmployeeID
from dbo.Orders
),
OrderDetailsTable as
(
Select OrderID as '訂單ID', ProductID as '產品ID', UnitPrice as '價格'
from dbo.[Order Details]
)
Select *
From OrdersTable A inner join OrderDetailsTable B
on A.訂單ID = B.訂單ID
範例三:CTE 遞迴 (參考:黑暗大的部落格文章)
資料清單
Code:
--如果CTE的WITH不在第一列, 前方要加上;
;WITH 公司組織結果(部門名稱, 直屬部門, 層級, 排序欄位)
AS
(
--Recursive CTE分為兩個部分, 第一部分為Anchor Member
--指不會被遞迴呼叫到的部分
SELECT 部門名稱, 直屬部門, 0, CONVERT(nvarchar(128), 部門ID)
FROM dbo.公司組織 WHERE 直屬部門=N'ROOT'
UNION ALL
--UNION ALL後方的部分稱為Recursive Member, 會在遞迴過程中反覆執行,
--直到無任何查詢結果為止
SELECT P.部門名稱, P.直屬部門, B.層級+1,
CONVERT(nvarchar(128), B.排序欄位 + '-' + CONVERT(nvarchar(128), P.部門ID))
FROM dbo.公司組織 P, 公司組織結果 B
WHERE P.直屬部門=B.部門名稱
)
SELECT (REPLICATE(' ', 層級) + 部門名稱) as '部門名稱', 層級, 排序欄位
FROM 公司組織結果
ORDER BY 排序欄位
另一個 CTE 遞迴範例 (參考:Journey to SQL Authority with Pinal Dave)
Code:
USE AdventureWorks
GO
WITH Emp_CTE AS (
--找出 ManagerID 為 NULL 的資料當作 Anchor Member
SELECT EmployeeID, ContactID, LoginID, ManagerID, Title, BirthDate
FROM HumanResources.Employee
WHERE ManagerID IS NULL
UNION ALL
--之後以 Anchor Member 為依據遞迴查詢
SELECT e.EmployeeID, e.ContactID, e.LoginID, e.ManagerID, e.Title, e.BirthDate
FROM HumanResources.Employee e
INNER JOIN Emp_CTE ecte ON ecte.EmployeeID = e.ManagerID
)
SELECT *
FROM Emp_CTE
GO
參考:
SQL 2005 T-SQL Enhancement: Common Table Expression
SQL SERVER – Simple Example of Recursive CTE
WITH common_table_expression (Transact-SQL)
利用CTE將分頁資料取出-Stored Procedure篇