Skip to content

3482. Analyze Organization Hierarchy 👍

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
WITH RECURSIVE
  EmployeeHierarchy AS (
    -- Base case: direct reports to CEO
    SELECT
      employee_id,
      employee_name,
      manager_id,
      salary,
      1 AS level
    FROM Employees
    WHERE manager_id IS NULL
    UNION ALL
    -- Recursive case: reports of reports
    SELECT
      Employees.employee_id,
      Employees.employee_name,
      Employees.manager_id,
      Employees.salary,
      EmployeeHierarchy.level + 1
    FROM Employees
    INNER JOIN EmployeeHierarchy
      ON (Employees.manager_id = EmployeeHierarchy.employee_id)
  ),
  -- Calculate team size and budget for each employee
  TeamSizeAndBudget AS (
    WITH RECURSIVE
      -- Get all subordinates (direct and indirect)
      Subordinates AS (
        -- Base case: direct reports
        SELECT
          manager_id,
          employee_id,
          salary
        FROM Employees
        WHERE manager_id IS NOT NULL
        UNION ALL
        -- Recursive case: indirect reports
        SELECT
          Subordinates.manager_id,
          Employees.employee_id,
          Employees.salary
        FROM Employees
        INNER JOIN Subordinates
          ON (Employees.manager_id = Subordinates.employee_id)
      )
    SELECT
      Employees.employee_id,
      COUNT(DISTINCT Subordinates.employee_id) AS team_size,
      IFNULL(SUM(Subordinates.salary), 0) + Employees.salary AS total_budget
    FROM Employees
    LEFT JOIN Subordinates
      ON (Employees.employee_id = Subordinates.manager_id)
    GROUP BY Employees.employee_id, Employees.salary
  )
SELECT
  EmployeeHierarchy.employee_id,
  EmployeeHierarchy.employee_name,
  EmployeeHierarchy.level,
  IFNULL(TeamSizeAndBudget.team_size, 0) AS team_size,
  IFNULL(TeamSizeAndBudget.total_budget, EmployeeHierarchy.salary) AS budget
FROM EmployeeHierarchy
LEFT JOIN TeamSizeAndBudget
  USING (employee_id)
ORDER BY
  EmployeeHierarchy.level,
  TeamSizeAndBudget.total_budget DESC,
  EmployeeHierarchy.employee_name;