繁体   English   中英

给定层次结构中的任何孩子,通过 INFORMIX 层次结构 SQL 获取完整的树

[英]Given any child in the hierarchy, fetch complete tree by INFORMIX hierarchical SQL

我需要一些有关 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,我应该能够获取输入employee 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;

这将工作正常,但如果我可以在单个查询中实现这一点,那就太好了。

这将您的两个查询合并为一个,并且似乎可以正常工作:

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。

受到乔纳森(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;

这似乎也很好。

在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;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM