通用表表达式(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

 

 

posted @ 2015-03-12 20:30  niaomingjian  阅读(1699)  评论(0编辑  收藏  举报