Sql 如何从Postgres表中列出管理级别

Sql 如何从Postgres表中列出管理级别,sql,database,postgresql,select,recursive-query,Sql,Database,Postgresql,Select,Recursive Query,我有一个包含以下字段的表: Id、经理Id和候选人姓名 经理id将指向允许我参考管理链的id。我希望生成如下输出: id | manager_id | level | ord -------+------------+-------+-------------------------------------------------- 2 | 12 | 3 | 26

我有一个包含以下字段的表: Id、经理Id和候选人姓名

经理id将指向允许我参考管理链的id。我希望生成如下输出:

  id   | manager_id | level |                       ord                        
-------+------------+-------+--------------------------------------------------
     2 |         12 |     3 | 261,226,12,2
     3 |          2 |     4 | 261,226,12,2,3
     4 |        106 |     4 | 261,226,110,106,4
     5 |          4 |     5 | 261,226,110,106,4,5
     6 |         86 |     4 | 261,226,12,86,6
     7 |        920 |     6 | 261,226,12,86,6,920,7
     8 |         86 |     4 | 261,226,12,86,8
     9 |          8 |     5 | 261,226,12,86,8,9
    10 |        145 |     5 | 261,226,12,4209,145,10
    11 |        139 |     7 | 261,226,12,4209,145,10,139,11
    12 |        226 |     2 | 261,226,12
    13 |       4209 |     4 | 261,226,12,4209,13
    14 |        159 |     5 | 261,226,12,69,159,14
    15 |         14 |     6 | 261,226,12,69,159,14,15
    16 |        110 |     3 | 261,226,110,16
id |候选人姓名|经理id |一级经理id |一级经理候选人姓名|二级经理id |二级经理候选人姓名|等

我最终希望构建这种结构的csv,以便在报告中利用它

到目前为止,我使用了以下查询来接近这一点:

CREATE EXTENSION tablefunc;

SELECT * FROM connectby('job', 'id', 'manager_id', '261', 0, ',') AS t(id int, manager_id int, level int, ord text) order by id;
其输出如下:

  id   | manager_id | level |                       ord                        
-------+------------+-------+--------------------------------------------------
     2 |         12 |     3 | 261,226,12,2
     3 |          2 |     4 | 261,226,12,2,3
     4 |        106 |     4 | 261,226,110,106,4
     5 |          4 |     5 | 261,226,110,106,4,5
     6 |         86 |     4 | 261,226,12,86,6
     7 |        920 |     6 | 261,226,12,86,6,920,7
     8 |         86 |     4 | 261,226,12,86,8
     9 |          8 |     5 | 261,226,12,86,8,9
    10 |        145 |     5 | 261,226,12,4209,145,10
    11 |        139 |     7 | 261,226,12,4209,145,10,139,11
    12 |        226 |     2 | 261,226,12
    13 |       4209 |     4 | 261,226,12,4209,13
    14 |        159 |     5 | 261,226,12,69,159,14
    15 |         14 |     6 | 261,226,12,69,159,14,15
    16 |        110 |     3 | 261,226,110,16
ord专栏为我提供了管理链,但我遇到了一个难题,那就是如何使用我正在寻找的mgr级别生成专栏。这也不一定只存在于SQL中


请注意,管理层可以深入到青少年。感谢您对如何处理此问题的任何想法

如果您事先知道层次结构中的最大级别数(例如,3),则有一个选项使用递归查询和条件聚合:

with recursive cte as (
    select id employee_id, id, manager_id, candidate_name, 0 lvl from mytable
    union all
    select c.employee_id, t.id, t.manager_id, t.candidate_name, lvl + 1
    from cte c
    inner join mytable t on t.id = c.manager_id
)
select 
    employee_id,
    max(case when lvl = 1 then id             end) level1_manager_id,
    max(case when lvl = 1 then candidate_name end) level1_candidate_name,
    max(case when lvl = 2 then id             end) level2_manager_id,
    max(case when lvl = 2 then candidate_name end) level2_candidate_name
    max(case when lvl = 2 then id             end) level3_manager_id,
    max(case when lvl = 2 then candidate_name end) level3_candidate_name
from cte
group by employee_id
您可以使用更多列来扩展
where
子句,以处理其他级别。当给定员工的层次结构耗尽时,其他列将显示
null


另一方面,如果要根据层次结构中的员工深度动态创建列,则需要更复杂的动态SQL。

第四行末尾缺少一个
。还需要在最后2条最大线上将lvl=2更改为3,否则这会起作用。谢谢,还有更多的后续行动。我希望0级总是从一个特定的经理开始,然后从那里向下扩展。示例Jill Smith是首席执行官,希望她对所有用户都是0级,并让候选人和Jill Smith之间的管理链填写这些级别。任何关于如何实现这一点的想法。在我上面的例子中,它使用261作为第一级。