1

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

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

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

我有列(员工、经理、工资)的表。需要在一条 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 

经理-员工分层可以有多个层次。

4

3 回答 3

4

这是一个递归查询。之前的部分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 Server 中的递归查询:https ://technet.microsoft.com/en-us/library/ms186243(v=sql.105).aspx 。

于 2016-12-20T12:07:09.250 回答
2

编辑 - 减少过度杀戮

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

退货

TopLvl  Salary
F       13
T       26
于 2016-12-20T12:15:20.000 回答
1

内部with T1引用INNER JOIN T1 ON r.[Manager]=T1.[Emp]可能是您的数据库中的表。对声明结果的外部with T1引用with

于 2016-12-20T11:42:45.970 回答