通过SQL查询分层数据

时间:2014-04-08 08:46:16

标签: sql oracle hierarchical-data recursive-query

问题:

通过SQL查询分层数据的不同方式,用于查询分支信息的子集。

案例研究:

员工表:

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)    

前提:

总裁是没有经理的雇员,即无效。

有叶节点,例如管理无人的开发人员,即employee_id不在manager_id中。

有第一线经理管理开发人员,第二线经理管理第一线等等.....

我可以从下面查询所有经理:

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;

和下面的总统:

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;

如何通过exists关键字获得第二线经理?

如何在不使用exists的情况下获得第二线经理?

获取分层数据的不同方法有哪些?

还有关于查询的性能。

2 个答案:

答案 0 :(得分:2)

这是一次性获取所有内容的基本查询:

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

LEVEL查询中可用的connect by伪列定义了距起点的距离(由start with定义)。所以总统有level = 1

如果您只想要第二线经理,只需添加where level = 3即可 声明。让第一线经理使用where level = 2

答案 1 :(得分:0)

在这里,我得到了二线经理,欢迎任何其他方式。谢谢。

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;