如何从 Postgres 中列出管理级别 table
How to list out management levels from Postgres table
我有一个包含以下字段的 table:
ID、manager_id 和 candidate_name
manager_id 将指向允许我引用管理链的 id。我想生成如下输出:
编号 | candidate_name | manager_id | lvl1 mgrID | lvl1 经理候选人姓名 | lvl2 mgrID | lvl2 经理候选人姓名 |等...
我最终想构建一个这种结构的 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 列为我提供了管理链,但我在如何生成具有我正在寻找的管理器级别的列方面遇到了困难。这也不一定只存在于 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,这要多得多复杂。
我有一个包含以下字段的 table: ID、manager_id 和 candidate_name
manager_id 将指向允许我引用管理链的 id。我想生成如下输出:
编号 | candidate_name | manager_id | lvl1 mgrID | lvl1 经理候选人姓名 | lvl2 mgrID | lvl2 经理候选人姓名 |等...
我最终想构建一个这种结构的 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 列为我提供了管理链,但我在如何生成具有我正在寻找的管理器级别的列方面遇到了困难。这也不一定只存在于 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,这要多得多复杂。