Oracle:层次查询连接依据

时间:2019-12-19 19:12:35

标签: sql oracle hierarchy connect-by

我编写了一个Oracle分层查询,它将为我们提供特定员工的高级管理人员。

例如 如果我们有示例Emp和Manager映射,例如:

WITH emp_manager_mapping AS (
 select 'A' empId, 'B' managerId,sysdate-100 appliedOn,'Success' status from dual
 union all
 select 'C' empId, 'D' managerId, sysdate-70 appliedOn, 'Success' status from dual
  union all
 select 'B' empId, 'C' managerId, sysdate-50 appliedOn,'Success' status from dual
 )select * from emp_manager_mapping; 

输出为:

A   B   10-SEP-19   Success
C   D   10-OCT-19   Success
B   C   30-OCT-19   Success

此后,我们对该数据集应用了层次查询,然后查找谁是雇员ID为“ A”的最高管理者:

WITH emp_manager_mapping AS (
 select 'A' empId, 'B' managerId,sysdate-100 appliedOn,'Success' status from dual
 union all
 select 'C' empId, 'D' managerId, sysdate-70 appliedOn, 'Success' status from dual
  union all
 select 'B' empId, 'C' managerId, sysdate-50 appliedOn,' Success' status from dual
 ) SELECT
    CONNECT_BY_ROOT ( empid ) AS empid,
    CONNECT_BY_ROOT ( managerid ) AS managerid,
    managerid AS top_manager_id,
    level
FROM
    emp_manager_mapping
WHERE
    CONNECT_BY_ISLEAF = 1 and status = 'Success'
START WITH
    empid = 'A'
CONNECT BY NOCYCLE
    PRIOR managerid = empid;

比输出是:

Value of top_manager_id is D

根据查询,它提供查询但不提供应用日期,如果我们还考虑了最近的应用日期,则必须忽略

C   D   10-OCT-19   Success record.

,我希望最终输出的top_manager id应该为“ C”

任何人都可以帮助找到预期的结果吗?

2 个答案:

答案 0 :(得分:1)

查找层次结构中的所有行,然后按appliedOn对这些行进行排序,并仅保留最新行:

查询

WITH emp_manager_mapping ( empid, managerid, appliedon, status ) AS (
  select 'A', 'B', sysdate-100,'Success' from dual union all
  select 'C', 'D', sysdate-70, 'Success' from dual union all
  select 'B', 'C', sysdate-50, 'Success' from dual
)
SELECT managerid AS top_managerid,
       LEVEL AS depth,
       CONNECT_BY_ROOT ( empid ) AS empid,
       CONNECT_BY_ROOT ( managerid ) AS managerid
FROM   emp_manager_mapping e
WHERE  status = 'Success'
START WITH empid = 'A'
CONNECT BY NOCYCLE
       PRIOR managerid = empid
ORDER BY AppliedOn DESC
FETCH FIRST ROW ONLY;

输出

TOP_MANAGERID | DEPTH | EMPID | MANAGERID
:------------ | ----: | :---- | :--------
C             |     2 | A     | B        

db <>提琴here

答案 1 :(得分:0)

  

并且我希望最终输出的top_manager id应该为“ C”

为什么?因为C-D关系是appliedOn早于B-> C关系的日期?

如果是的话,这就是您要寻找的吗?

WITH emp_manager_mapping AS (
 select 'A' empId, 'B' managerId,sysdate-100 appliedOn,'Success' status from dual
 union all
 select 'C' empId, 'D' managerId, sysdate-70 appliedOn, 'Success' status from dual
  union all
 select 'B' empId, 'C' managerId, sysdate-50 appliedOn,'Success' status from dual
 ) SELECT
    CONNECT_BY_ROOT ( empid ) AS empid,
    CONNECT_BY_ROOT ( managerid ) AS managerid,
    managerid AS top_manager_id,
    level
FROM
    emp_manager_mapping
WHERE
    CONNECT_BY_ISLEAF = 1
START WITH
    empid = 'A'
CONNECT BY NOCYCLE
    empid  = PRIOR managerid
    AND appliedOn >= PRIOR appliedOn
    AND status = 'Success'
    ;
+-------+-----------+----------------+-------+
| EMPID | MANAGERID | TOP_MANAGER_ID | LEVEL |
+-------+-----------+----------------+-------+
| A     | B         | C              |     2 |
+-------+-----------+----------------+-------+

此外,请注意,我将status='Success'的支票移到了CONNECT BY。根据您的要求,这可能是对还是错。但我想指出这一点,因为如果叶行不是“成功”,则拥有WHERE子句将导致查询获得零行(因为对WHERE子句进行了评估CONNECT BY之后