以下SQL查询如何工作?

时间:2016-12-20 11:36:09

标签: sql sql-server database database-management

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

setUserProperties

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

我有表格列(员工,经理,薪水)。需要计算一个SQL中与顶级经理相对应的所有员工的总薪水。例如

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

结果应该是:

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

Manager-Employee分层可以达到多个级别。

3 个答案:

答案 0 :(得分: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

答案 1 :(得分: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

答案 2 :(得分:1)

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