Мне нужно написать запрос на выбор менеджера и итоговую зарплату сотрудников под менеджером.

Заработная плата сотрудников должна повышаться до Менеджера на основе иерархии. Mgrid ссылается на empid в той же таблице.

Таблица: Employee

EmpId  Name      Salary  Mgrid
:---- |:------:| :------:|-----:| 
1      CEO        10000    NULL
2      M2         8000      1
3      M3         6000      2
4      M4         6000      2
5      M5         5000      4
6      M6         1000      2
7      M7         500       5

Вывод должен быть ManagerName и Salary

Name     TotalSalary
----------------------
CEO      26,500  (total salary of all employees under him/her)
M2       18,500  (Salary of M3 +M4 + M5 + M6 + M7). 
M4        5,500  (salary of M5+M7)
M5          500  (Salary Of M7)

В приведенном выше примере: M2 имеет M3, M4, M6 непосредственно под ним. Также под M4 находится M5, а под M5 - M7. Таким образом, эти сотрудники также должны быть включены в общую сумму M2.

Я пробовал использовать рекурсивный CTE, но потерял зарплату.

Любая помощь приветствуется.

Запрос:


Create table Emp_Manager
(
 Empid int identity,
 EmpName varchar(100),
 Salary int,
 Mgrid int)

 insert into Emp_Manager  values('CEO',10000,NULL),('M2',8000,1),('M3',6000,2)
 ,('M4',6000,2),('M5',5000,4),('M6',1000,2),('M7',500,5)


 ;With Cte_manager as
     (Select Empid,Empname , Salary,Mgrid,0 AS Hierchacy  FROM Emp_Manager WHERE mgrid is null
      union all
      Select e.Empid,e.Empname ,e.Salary,e.Mgrid, Hierchacy + 1 AS Hierchacy FROM Emp_Manager as E
      inner join Cte_manager as c on e.mgrid = c.empid   
        ) ,
      cte_emp as (Select Empid,empname , Hierchacy,
      Sum(Salary) Over (order by Hierchacy rows between 1 following and unbounded following) AS Salary
      from Cte_manager)
      Select Empname  AS Managername,Salary as TotalSal FROM cte_emp as c
      WHERE Exists (Select 1 FROM Emp_Manager WHERE mgrid = c.empid)
      order by Hierchacy


Query  result: 
CEO 26500
M2  18500
M4  11500
M5  500

M4 неверен ... Я неправильно использую иерархию. Я не мог придумать другого пути,

1
Melvin 2 Мар 2021 в 00:20

1 ответ

Лучший ответ

Приведенное ниже решение назначает менеджерам зарплату 0 в качестве начала для рекурсивной суммы заработной платы их сотрудников. Это устраняет необходимость в столбце Hierarchy, втором CTE cte_emp или сложном агрегировании суммы (Sum(Salary) Over (order by Hierchacy rows between 1 following and unbounded following))

Примеры данных

create table Employee
(
  EmpId int,
  Name nvarchar(3),
  Salary money,
  MgrId int
);

insert into Employee (EmpId, Name, Salary, MgrId) values
(1, 'CEO', 10000, NULL),
(2, 'M2',   8000, 1),
(3, 'M3',   6000, 2),
(4, 'M4',   6000, 2),
(5, 'M5',   5000, 4),
(6, 'M6',   1000, 2),
(7, 'M7',    500, 5);

Решение

with rcte as
(
  select e.Name as ManagerName,
         convert(money, 0) as Salary,
         e.EmpId as EmpId
  from Employee e
  where exists ( select 'x'
                 from Employee ee
                 where ee.MgrId = e.EmpId)
union all
  select r.ManagerName,
         e.Salary,
         e.EmpId
  from rcte r
  join Employee e
    on e.MgrId = r.EmpId
)
select r.ManagerName,
       sum(r.Salary) as TotalSalary
from rcte r
group by r.ManagerName;

Результат

ManagerName  TotalSalary
-----------  -----------
CEO          26500.0000
M2           18500.0000
M4            5500.0000
M5             500.0000

Fiddle, чтобы увидеть все в действии с промежуточными шагами.

1
Sander 1 Мар 2021 в 22:34