Question

Problem:

Different ways of querying hierarchical data through SQL for querying subset of branch information.

Case study :

Employees table :

desc employees
Name           Null     Type         
-------------- -------- ------------ 
EMPLOYEE_ID    NOT NULL NUMBER(6)    
FIRST_NAME              VARCHAR2(20) 
LAST_NAME      NOT NULL VARCHAR2(25) 
MANAGER_ID              NUMBER(6)    
DEPARTMENT_ID           NUMBER(4)    

Premises:

President is an employee who doesn't have the manager i.e. null.

There are leaf nodes for eg developers who manages none i.e. employee_id not in manager_id.

There are 1rst line managers who manages developers, 2nd line managers who managers 1rst line and so on.....

I could all the managers from below query:

SELECT manager_id,
  employee_id
FROM EMPLOYEES o
WHERE EXISTS
  (SELECT * FROM EMPLOYEES i WHERE o.employee_id = i.manager_id)
AND manager_id IS NOT NULL
ORDER BY o.manager_id,
  o.EMPLOYEE_ID;

and president from below:

SELECT manager_id,
employee_id
    FROM EMPLOYEES o
    WHERE EXISTS
      (SELECT * FROM EMPLOYEES i WHERE o.employee_id = i.manager_id)
    AND manager_id IS NULL
    ORDER BY o.manager_id,
      o.EMPLOYEE_ID;

How should I get the 2nd line managers through exists key word ?

How should I get the 2nd line managers without using exists?

What are the different ways of getting the hierarchical data ?

And also regarding performance of queries.

Was it helpful?

Solution

This is the basic query that gets everything in one go:

select employee_id, first_name, last_name, 
       case 
          when level = 1 then 'President'
          when level = 2 then '1st line manager'
          when level = 3 then '2nd line manager'
          when connect_by_isleaf = 1 then 'Developer'
       end as employee_type
from employees
start with manager_id is null
connect by prior employee_id = manager_id

The LEVEL pseudo column available in a connect by query defines the distance from the start (which is defined by start with). So the president has level = 1

If you just want 2nd line managers, you can simply add where level = 3 to the statement. To get 1st line manager use where level = 2

OTHER TIPS

Here I got for second line managers, any other ways are welcomed.Thanks.

SELECT secondline_managers.employee_id,
  secondline_managers.manager_id
FROM employees secondline_managers
WHERE EXISTS
  (SELECT firstline_managers_anonymous.employee_id
  FROM
    (SELECT firstline_managers.employee_id,
      manager_id
    FROM employees firstline_managers
    WHERE EXISTS
      (SELECT all_managers.managers
      FROM
        (SELECT o.employee_id AS managers
        FROM employees o
        WHERE EXISTS
          (SELECT *
          FROM employees i
          WHERE o.employee_id=i.manager_id
          AND i.manager_id  IS NOT NULL
          )
        ) all_managers
      WHERE firstline_managers.employee_id=all_managers.managers
      AND firstline_managers.manager_id  IS NOT NULL
      )
    ORDER BY firstline_managers.employee_id
    ) firstline_managers_anonymous
  WHERE firstline_managers_anonymous.manager_id=secondline_managers.employee_id
  AND secondline_managers.manager_id IS NOT NULL
  )
ORDER BY secondline_managers.employee_id;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top