下面的 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
给定的查询如何正确,因为它在 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