我刚看了这个链接http://msdn.microsoft.com/en-us/library/ms186243.aspx
以下是创建表和插入数据的代码: -
-- Create an Employee table.
CREATE TABLE dbo.MyEmployees
(
EmployeeID smallint NOT NULL,
FirstName nvarchar(30) NOT NULL,
LastName nvarchar(40) NOT NULL,
Title nvarchar(50) NOT NULL,
DeptID smallint NOT NULL,
ManagerID int NULL,
CONSTRAINT PK_EmployeeID PRIMARY KEY CLUSTERED (EmployeeID ASC)
);
-- Populate the table with values.
INSERT INTO dbo.MyEmployees VALUES
(1, N'Ken', N'S�nchez', N'Chief Executive Officer',16,NULL)
,(273, N'Brian', N'Welcker', N'Vice President of Sales',3,1)
,(274, N'Stephen', N'Jiang', N'North American Sales Manager',3,273)
,(275, N'Michael', N'Blythe', N'Sales Representative',3,274)
,(276, N'Linda', N'Mitchell', N'Sales Representative',3,274)
,(285, N'Syed', N'Abbas', N'Pacific Sales Manager',3,273)
,(286, N'Lynn', N'Tsoflias', N'Sales Representative',3,285)
,(16, N'David',N'Bradley', N'Marketing Manager', 4, 273)
,(23, N'Mary', N'Gibson', N'Marketing Specialist', 4, 16);
他们已经给出了这个CTE: -
WITH DirectReports (ManagerID, EmployeeID, Title, DeptID, Level)
AS
(
-- Anchor member definition
SELECT e.ManagerID, e.EmployeeID, e.Title, edh.DepartmentID,
0 AS Level
FROM dbo.MyEmployees AS e
INNER JOIN HumanResources.EmployeeDepartmentHistory AS edh
ON e.EmployeeID = edh.BusinessEntityID AND edh.EndDate IS NULL
WHERE ManagerID IS NULL
UNION ALL
-- Recursive member definition
SELECT e.ManagerID, e.EmployeeID, e.Title, edh.DepartmentID,
Level + 1
FROM dbo.MyEmployees AS e
INNER JOIN HumanResources.EmployeeDepartmentHistory AS edh
ON e.EmployeeID = edh.BusinessEntityID AND edh.EndDate IS NULL
INNER JOIN DirectReports AS d
ON e.ManagerID = d.EmployeeID
)
-- Statement that executes the CTE
SELECT ManagerID, EmployeeID, Title, DeptID, Level
FROM DirectReports
INNER JOIN HumanResources.Department AS dp
ON DirectReports.DeptID = dp.DepartmentID
WHERE dp.GroupName = N'Sales and Marketing' OR Level = 0;
GO
得到了这个输出: -
ManagerID EmployeeID Title Level
--------- ---------- ----------------------------- ------
NULL 1 Chief Executive Officer 0
1 273 Vice President of Sales 1
273 16 Marketing Manager 2
273 274 North American Sales Manager 2
273 285 Pacific Sales Manager 2
16 23 Marketing Specialist 3
274 275 Sales Representative 3
274 276 Sales Representative 3
285 286 Sales Representative 3
好吧,我写了一个简单的连接查询,得到的结果几乎与级别编号相同: -
Select e.ManagerId,
m.FirstName as [Manager Name],
e.EmployeeId,
e.FirstName as [Employee Name],
e.Title
from dbo.MyEmployees e
LEFT JOIN dbo.MyEmployees m
On e.ManagerId = m.EmployeeId;
CTE的目的是打印级别号吗?谁能给我一些具体的例子,说明为什么需要CTE?
提前致谢:)
答案 0 :(得分:3)
如果您希望向所有下属显示经理级人员,该怎么办? (例如,所有“二级”员工与其下的任何人 - 作为直接报告或作为直接报告的报告,或作为直接报告直接报告的报告等)。
这对CTE来说相当简单。没有这种递归就不那么容易了。
CTE还可以使查询更具可读性,而不必在单个SQL语句中多次包含相同的子查询。当您更改一个子查询但忘记更改另一个子查询时,重复的维护也可能是一个问题。这也是许多地方的性能提升,因为SQL Server可以评估并保存一次CTE结果。
答案 1 :(得分:0)
另一个很好用于CTE的例子是删除重复项,这是我目前工作中的主要用途。代码使用示例:
WITH cte
AS ( SELECT * ,
ROW_NUMBER() OVER ( PARTITION BY PlantId, Plant,
DeliveryDate, RouteId, CustomerId,
ProductId, Quantity ORDER BY PlantId, Plant, DeliveryDate, RouteId, CustomerId, ProductId, Quantity ) AS Rowid
FROM dbo.RAW_ORDERS_WEST
)
DELETE FROM CTE
WHERE Rowid > 1