使用SQL Server CTE获取总计下线记录

时间:2017-03-14 02:14:36

标签: sql sql-server sql-server-2016

如何使用SQL将所有下线汇总到他们的直线上线。

  • 所有员工销售均为主管销售。
  • 所有主管销售均为经理的销售。
  • 所有经理销售均为负责人。

当前数据:

ID   Name     Role            Level      Reportingto     Sales
---------------------------------------------------------------
1    Joe      Head              1          NULL           0
2    Smith    Manager           2           1             0
3    Mike     Supervisor        3           2             0
4    Mitch    Staff             4           3             10
5    Jen      Staff             4           3             20
6    Ian      Manager           2           1             0
7    Jess     Supervisor        3           6             0
8    Rocky    Staff             4           7             5
9    Jessica  Supervisor        3           6             0
10   Rolly    Staff             4           9             3

理想输出

ID   Name     Role            Level      Reportingto     Sales
---------------------------------------------------------------
1    Joe      Head              1          NULL           38
2    Smith    Manager           2           1             30
3    Mike     Supervisor        3           2             30
4    Mitch    Staff             4           3             10
5    Jen      Staff             4           3             20
6    Ian      Manager           2           1             8
7    Jess     Supervisor        3           6             5
8    Rocky    Staff             4           7             5
9    Jessica  Supervisor        3           6             3
10   Rolly    Staff             4           9             3

我正在使用SQL Server 2016

4 个答案:

答案 0 :(得分:0)

您可以使用outer apply

select t1.id,t1.name,t1.role,t1.level,t1.reportingto,coalesce(t2.sales,t1.sales) as val
from t t1
outer apply (select sum(sales) as sales
             from t t2 
             where t1.id<=t2.id and t1.level<t2.level) t2

答案 1 :(得分:0)

可能有一种更简单的方法可以做到这一点,但在我看来,你需要从“工作人员”开始。并递归:

;with cte as (SELECT [ID], [Name], [Role], [Level], [Reportingto], [Sales], Sales as Sum_Sales
              FROM #Table1 
              WHERE [Role] = 'Staff'
              UNION ALL
              SELECT a.[ID], a.[Name], a.[Role], a.[Level], a.[Reportingto], a.[Sales], a.Sales + b.Sum_Sales AS Sum_Sales
              FROM #Table1 a
              JOIN cte b
                 ON b.Reportingto = a.ID
              )
SELECT [ID], [Name], [Role], [Level], [Reportingto],SUM(Sum_Sales) as Sales
FROM cte
GROUP BY [ID], [Name], [Role], [Level], [Reportingto]

答案 2 :(得分:0)

假设该表为KTemp,我创建了一个新列。希望这可以帮助。

 SELECT *,
           CASE
               WHEN LEVEL=1 THEN
                      (SELECT sum(Sales)
                       FROM KTemp x
                       WHERE x.Level IN (1,
                                         2,
                                         3,
                                         4) )
               WHEN LEVEL=2 THEN
                      (SELECT sum(Sales)
                       FROM KTemp x
                       WHERE x.Level IN (2,
                                         3,
                                         4) )
               WHEN LEVEL=3 THEN
                      (SELECT sum(Sales)
                       FROM KTemp x
                       WHERE x.Level IN (3,
                                         4) )
               WHEN LEVEL=4 THEN
                      (SELECT sum(Sales)
                       FROM KTemp x
                       WHERE x.Level IN (4) )
           END AS [Up-line Sales]
    FROM KTemp

答案 3 :(得分:0)

Declare @YourTable table (ID int,Name varchar(25),Role varchar(25),Level int,Reportingto int,Sales int)
Insert into @YourTable values 
(1    ,'Joe'      ,'Head'              ,1           ,NULL          ,0),
(2    ,'Smith'    ,'Manager'           ,2           ,1             ,0),
(3    ,'Mike'     ,'Supervisor'        ,3           ,2             ,0),
(4    ,'Mitch'    ,'Staff'             ,4           ,3             ,10),
(5    ,'Jen'      ,'Staff'             ,4           ,3             ,20),
(6    ,'Ian'      ,'Manager'           ,2           ,1             ,0),
(7    ,'Jess'     ,'Supervisor'        ,3           ,6             ,0),
(8    ,'Rocky'    ,'Staff'             ,4           ,7             ,5),
(9    ,'Jessica'  ,'Supervisor'        ,3           ,6             ,0),
(10   ,'Rolly'    ,'Staff'             ,4           ,9             ,3)


Declare @Top int = null --<<  Sets top of Hier Try 6

;with cteP as (
      Select Seq  = cast(10000+Row_Number() over (Order by Name) as varchar(500))
            ,ID
            ,Reportingto 
            ,Lvl=1
            ,Name 
            ,Role
            ,Sales
      From   @YourTable 
      Where  IsNull(@Top,-1) = case when @Top is null then isnull(Reportingto ,-1) else ID end
      Union  All
      Select Seq  = cast(concat(p.Seq,'.',10000+Row_Number() over (Order by r.Name)) as varchar(500))
            ,r.ID
            ,r.Reportingto 
            ,p.Lvl+1
            ,r.Name 
            ,r.Role
            ,r.Sales
      From   @YourTable r
      Join   cteP p on r.Reportingto  = p.ID)
Select A.ID
      ,A.Name
      ,A.Role
      ,A.Lvl
      ,A.Reportingto 
      ,Sales  = (Select sum(Sales) from cteP where  Seq Like A.Seq+'%')
    From cteP A
    Order By A.Seq

<强>返回

enter image description here