通用表表达式(Common Table Expression)
问题:编写由基本的 SELECT/FROM/WHERE 类型的语句派生而来的复杂 SQL 语句。
方案1:编写在From子句内使用派生表(内联视图)的T-SQL查询语句。
方案2:使用视图
方案3:使用通用表达式(CTE)
比较:
视图:通常用于分解大型查询,无需在临时表中复制或存储数据,数据库中可以重复使用。
1 CREATE VIEW vwMyView AS 2 SELECT 3 EmployeeID, COUNT(*) AS NumOrders, MAX(OrderDate) AS MaxDate 4 FROM Orders 5 GROUP BY EmployeeID 6 GO 7 8 SELECT 9 e.EmployeeID, oe.NumOrders, oe.MaxDate, e.ReportsTo AS ManagerID, 10 om.NumOrders, om.MaxDate 11 FROM 12 Employees AS e 13 INNER JOIN vwMyView AS oe ON e.EmployeeID = oe.EmployeeID 14 INNER JOIN vwMyView AS om ON e.ReportsTo = om.EmployeeID
派生表:只能在派生表所在的语句中访问它们,使查询变得更难以阅读和维护(若同一个批处理中要多次使用派生表,必须复制粘贴派生表)
1 SELECT 2 e.EmployeeID, oe.NumOrders, oe.MaxDate, e.ReportsTo AS ManagerID, 3 om.NumOrders, om.MaxDate 4 FROM 5 Employees AS e 6 INNER JOIN 7 (SELECT EmployeeID, COUNT(*), MAX(OrderDate) 8 FROM Orders 9 GROUP BY EmployeeID) AS oe(EmployeeID, NumOrders, MaxDate) 10 ON e.EmployeeID = oe.EmployeeID 11 LEFT JOIN 12 (SELECT EmployeeID, COUNT(*), MAX(OrderDate) 13 FROM Orders 14 GROUP BY EmployeeID) AS om(EmployeeID, NumOrders, MaxDate) 15 ON e.ReportsTo = om.EmployeeID
CET:提升了 T-SQL 的可读性(就像视图一样),在同一个批处理后紧跟的查询中多次使用,不会在内部创建临时表或虚拟表
1 ;WITH EmpOrdersCTE (EmployeeID, NumOrders, MaxDate) AS 2 ( 3 SELECT EmployeeID, COUNT(*), MAX(OrderDate) 4 FROM Orders 5 GROUP BY EmployeeID 6 ) 7 8 SELECT 9 e.EmployeeID, oe.NumOrders, oe.MaxDate, 10 e.ReportsTo AS ManagerID, om.NumOrders, om.MaxDate 11 FROM 12 Employees AS e 13 INNER JOIN EmpOrdersCTE oe ON e.EmployeeID = oe.EmployeeID 14 LEFT JOIN EmpOrdersCTE om ON e.ReportsTo = om.EmployeeID