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

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

我需要一些有关 Informix 分层 sql 查询的帮助。我有 table 结构如下:

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;

其中 return 是上面 table 中指定的确切层次结构。但是,我试图在这里实现一些不同的东西。给定层次结构中的任何员工 ID 作为输入,我试图获得相同的 result-set。例如,在查询中,如果我将 5154 指定为输入 employee_id,我应该能够获得所有 parent 及其 children 以及 children 和 grand-children 输入的员工 ID。准确地说,我想要的 result-set 与我通过 运行ning 上述查询得到的完全相同。

是否可以在单个查询中实现?如果是的话,你能帮我实现这个吗?

                         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 ;

这将 return:

employee_id      |   manager_id
5148    
5149                  5148
5150                  5149

然后我们可以通过迭代 result-set 在应用层检索 parent 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;

基本上,这需要你的查询在层次结构中运行并运行它,然后过滤结果以获得最高经理(没有经理的员工),并将该值用作 'hierarchic descent from top'查询。

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;

这似乎也能正常工作。

您可以在临时 table 的帮助下使用简单的合并语句,而不是使用分层查询,以在 informix 12 及更高版本中获得所需的结果。

使用以下 stmt 创建临时 table:

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;