我编写了一个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”
任何人都可以帮助找到预期的结果吗?
答案 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
之后。