0

I am having difficulties trying to output all managers above an employee. The employees table does not have a manager_id column, which makes this a bit complicated.

The hierarchy is defined in a references table. Each employee belongs to a department and is assigned a position. A position with level 1 is a manager, level 0 is non-manager.

To get the manager of a manager, we take the parent_id of the current department and look for an employee assigned with a position with level 1.

The function I currently have only returns the employee's direct manager (from the non-recursive term).

CREATE OR REPLACE FUNCTION public.get_employee_managers(employees_row employees)
 RETURNS SETOF employees
 LANGUAGE sql
 STABLE
AS $function$
WITH RECURSIVE managers AS (
    SELECT e1.*
    FROM
      employees e1
      JOIN "references" AS employees_row_department ON employees_row_department.id = employees_row.department_id
      JOIN "references" AS e1_department ON e1_department.id = e1.department_id
      JOIN "references" AS e1_position ON e1_position.id = e1.position_id
    WHERE
      e1_department.id = employees_row_department.parent_id AND e1_position.level = 1 AND e1.active = 1 AND e1.is_deleted = false
    OR
      e1_department.id = employees_row.department_id AND e1_position.level = 1 AND e1.active = 1 AND e1.is_deleted = false AND e1.id <> employees_row.id
    UNION
    SELECT m1.*
    FROM
      managers m1
      JOIN "references" AS m1_department ON m1_department.id = m1.department_id
      JOIN "references" AS m1_position ON m1_position.id = m1.position_id
      INNER JOIN employees AS e2 ON (m1_department.parent_id = e2.department_id AND m1_position.level = 1 AND e2.active = 1 AND e2.is_deleted = false)
)
SELECT * FROM managers ORDER BY department_id ASC
$function$

Using the following recursive term gives me the same result as the one above

SELECT e2.*
    FROM
      employees e2
      JOIN "references" AS e2_department ON e2_department.id = e2.department_id
      JOIN "references" AS e2_position ON e2_position.id = e2.position_id
      INNER JOIN managers m1 ON m1.id = e2.id
      JOIN "references" AS m1_department ON m1_department.id = m1.department_id
    WHERE
      e2_department.id = m1_department.parent_id AND e2_position.level = 1 AND e2.active = 1 AND e2.is_deleted = false
dimbslmh
  • 1,801
  • 1
  • 12
  • 8

1 Answers1

0

Changing the second recursive term seems to give me the result I was looking for.

      INNER JOIN managers m1 ON m1.id = e2.id

to

      INNER JOIN managers m1 ON m1.id <> e2.id
dimbslmh
  • 1,801
  • 1
  • 12
  • 8