下面的 SQL 查询是如何工作的?

How the following SQL query is working?

给定的查询如何正确,因为它在 with 子句中使用 T1,并且 T1 是在 WITH 中的子句完成后声明的。

WITH T1(Emp,Manager,Salary) AS 
( 
SELECT tt2.[Emp],tt2.[Manager],tt2.[Salary] 
FROM [YourTable] AS tt1 
RIGHT OUTER JOIN [YourTable] AS tt2 ON tt1.[Emp]=tt2.[Manager] 
WHERE tt1.[Emp] is NULL 
UNION ALL 
SELECT r.[Emp],T1.[Manager],r.[Salary] 
FROM [YourTable] AS r 
INNER JOIN T1 ON r.[Manager]=T1.[Emp] 
) 
SELECT [Manager],SUM([Salary]) AS Salary 
FROM T1 
GROUP BY [Manager] 
ORDER BY SUM([Salary]) DESC

以上查询是对以下问题的回答 -

我有 table 列(员工、经理、薪水)。需要计算一个SQL中高层管理人员对应的所有员工的工资总和。例如

Input table is : 
Emp Manager Salary 
A   T   10 
B   A   11 
C   F   13 
D   B   5 

结果应该是:

Top-Lvl Manager Salary(agg) 
T   26 
F   13 

经理-员工分层可以达到多个级别。

内部 with T1 引用 INNER JOIN T1 ON r.[Manager]=T1.[Emp] 可能是您数据库中的 table。在 with T1 之外引用 with 语句的结果。

这是一个递归查询。 UNION ALL 之前的部分获取基本记录。它之后的部分递归地获得更多的行附加到前者。

第一部分写得乱七八糟。它是一种反连接模式,即使使用许多人认为难以阅读的右外部连接也能实现。它仅仅意味着:

select emp, manager, salary 
from yourtable
where manager not in (select emp from yourtable);

所以你得到所有没有经理的员工(即超级经理)。

UNION ALL之后的部分你得到他们的下属和这些的下属等。一个层次查询。

终于在

SELECT [Manager],SUM([Salary]) AS Salary 
FROM T1 
GROUP BY [Manager] 
ORDER BY SUM([Salary]) DESC

您使用这些行来获得每个经理的累计工资。

您可以在 SQL 服务器中阅读递归查询:https://technet.microsoft.com/en-us/library/ms186243(v=sql.105).aspx

EDIT - Less over-kill

Declare @YourTable table (Emp varchar(25),Manager varchar(25),Salary int)
Insert into @YourTable values 
('A','T',10),
('B','A',11), 
('C','F',13),
('D','B',5) 

;with cteP as (
      Select Seq  = cast(1000+Row_Number() over (Order by Emp) as varchar(500))
            ,Emp=Manager
            ,Manager=cast(null as varchar(25))
            ,Lvl=1
            ,Salary = 0
      From  @YourTable 
      Where Manager Not In (Select Distinct Emp From @YourTable)
      Union  All
      Select Seq  = cast(concat(p.Seq,'.',1000+Row_Number() over (Order by r.Emp)) as varchar(500))
            ,r.Emp
            ,r.Manager
            ,p.Lvl+1
            ,r.Salary
      From   @YourTable r
      Join   cteP p on r.Manager = p.Emp)
Select TopLvl = A.Emp
      ,Salary = sum(B.Salary)
 from cteP A
 Join cteP B on (B.Seq Like A.Seq+'%')
 Where A.Lvl=1
 Group By A.Emp

Returns

TopLvl  Salary
F       13
T       26