【问题标题】:How the following SQL query is working?下面的 SQL 查询是如何工作的?
【发布时间】:2016-12-20 11:36:09
【问题描述】:

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

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

【问题讨论】:

标签: sql sql-server database database-management


【解决方案1】:

这是一个递归查询。 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。

【讨论】:

    【解决方案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
    

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 我不这么认为。没有其他名为 T1 的表。它使用 T1 是因为它需要递归地执行单层以实现经理-员工多层。
      • 如果您确定没有 T1 表或同义词,则意味着 Thorsten 的答案在这里有效。
      猜你喜欢
      • 1970-01-01
      • 2012-12-18
      • 1970-01-01
      • 1970-01-01
      • 2023-02-11
      • 2011-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多