我需要一些Informix层次结构sql查询的帮助。我有以下结构的表:
create table empl_relation (
employee_id char(10),
manager_id char(10));
employee_id | manager_id
5148 null
5149 5148
5150 5149
5151 5148
5152 5151
5154 5148
5155 5154
我能够成功运行以下查询:
SELECT employee_id, manager_id FROM empl_relation
START WITH employee_id = 5148
CONNECT BY PRIOR employee_id = manager_id
ORDER SIBLINGS BY employee_id;
返回上表中指定的确切层次结构。但是,我想在这里尝试不同的东西。我试图获得相同的结果集,给定层次结构中的任何员工ID作为输入。例如,在查询中,如果我指定5154作为输入employee_id,我应该能够获得所有父母及其子女以及输入员工ID的子女和子女。确切地说,我想要通过运行上面提到的查询得到完全相同的结果集。
是否可以在单个查询中实现?如果是的话,你能帮助我实现这个目标吗?
EDIT
好的,我已经找到了实现这一目标的一种方法,但它涉及执行2个查询,如下所示:
SELECT employee_id, manager_id FROM empl_relation
START WITH employee_id = 5150
CONNECT BY employee_id = PRIOR manager_id
ORDER SIBLINGS BY employee_id ;
将返回:
employee_id | manager_id
5148
5149 5148
5150 5149
然后我们可以通过遍历结果集然后执行以下查询来获取完整的分层树来检索应用层上的父employee_id:
SELECT employee_id, manager_id FROM empl_relation
START WITH employee_id = 5148
CONNECT BY PRIOR employee_id = manager_id
ORDER SIBLINGS BY employee_id;
这样可以正常工作,但如果我能在单个查询中实现这一点,那真的很棒。
答案 0 :(得分:2)
这将您的两个查询合并为一个,似乎有效:
SELECT employee_id, manager_id FROM empl_relation
START WITH employee_id = (
SELECT h.employee_id
FROM (SELECT employee_id, manager_id
FROM empl_relation
START WITH employee_id = 5150
CONNECT BY employee_id = PRIOR manager_id
) AS h
WHERE h.manager_id IS NULL)
CONNECT BY PRIOR employee_id = manager_id
ORDER BY employee_id;
基本上,这会使您的查询在层次结构中运行并运行它,然后过滤结果以获得最高管理者(没有经理的员工),并将该值用作“顶层的层次下降”中的START查询。
5148
5149 5148
5150 5149
5151 5148
5152 5151
5154 5148
5155 5154
我得到的结果与任何起始值相同:5148,5149,5150,5151,5152,5154,5155。
答案 1 :(得分:2)
受Jonathan的回复启发,我提出了他的查询的简短版本,如下所示
SELECT employee_id,manager_id FROM empl_relation
START WITH employee_id =
(SELECT employee_id
FROM empl_relation er
WHERE er.manager_id IS NULL
START WITH employee_id = 5150 CONNECT BY employee_id =
PRIOR manager_id)
CONNECT BY
PRIOR employee_id = manager_id
ORDER BY employee_id;
这似乎也很好。
答案 2 :(得分:0)
在informix 12 及更高版本中,您可以在临时表的帮助下使用简单的合并语句来实现所需的结果,而不是使用分层查询。
使用以下 stmt 创建临时表:
select a.employee_id,
a.manager_id,
rpad(a.manager_id, 100, ' ') as manager_hier,
a.manager_id as topmanager
from empl_relation a
left join empl_relation b on a.manager_id = b.employee_id into temp emp_mgr_rel;
运行下面的合并 stmt 次数与树的最长分支的深度一样多。多运行它不会影响最终结果,所以不用担心:
merge into emp_mgr_rel as a using emp_mgr_rel as b on a.topmanager = b.employee_id WHEN MATCHED THEN
UPDATE
set a.manager_hier = nvl(trim(a.manager_hier), '') || '-' || nvl(trim(b.topmanager), ''),
a.topmanager = trim(b.manager_hier);
使用以下 stmt 检查您的结果。您将在 manager_hier
列下看到作为带连字符的值的层次结构:
select employee_id, manager_hier from emp_mgr_rel;