我无法在PostgreSQL中组合一个递归查询来显示跨员工的管理层次结构。为了实现这一点,我需要将表自连接到自身,直到每个员工都到达其层次结构的末尾。我的数据看起来像这样在某一天:
+------------+-------------+-----------------+---------------------+
| date | employee_id | terminated_flag | manager_employee_id |
+------------+-------------+-----------------+---------------------+
| 2019-01-31 | 3 | 0 | 2 |
| 2019-01-31 | 2 | 1 | 1 |
| 2019-01-31 | 1 | 0 | |
+------------+-------------+-----------------+---------------------+
在理想情况下,我想创建一个包含给定雇员的完整的层次和经理细节JSONB列。我知道我可以通过递归追加到现有的JSONB列,但是要达到这一点一直很困难。所需的输出看起来像这样(为了易于阅读而删除了列):
+------------+-------------+-----------------------------------------------------------+
| date | employee_id | manager_hierarchy |
+------------+-------------+-----------------------------------------------------------+
| 2019-01-31 | 3 | {{"level":1,"id":2,"term":1},{"level":2,"id":1,"term":0}} |
| 2019-01-31 | 2 | {{"level":1,"id":1,"term":0}} |
| 2019-01-31 | 1 | |
+------------+-------------+-----------------------------------------------------------+
在我的数据集,可能有N个级别从任何给定员工的CEO了,所以递归我必须结束后每一位员工已经达到了CEO,谁还会有manager_employee_id NULL值。
这可能吗?感谢您的帮助!
答案 0 :(得分:0)
我将其视为递归CTE以获取层次结构,然后进行聚合以创建jsonb值:
with recursive t as (
select v.*
from (values (3, 2, 0), (2, 1, 1), (1, null, 0)) v(employee_id, manager_employee_id, terminated_flag)
),
cte as (
select distinct employee_id, manager_employee_id, terminated_flag, 1 as lev
from t
union all
select cte.employee_id, t.manager_employee_id, t.terminated_flag, lev + 1
from cte join
t
on cte.manager_employee_id = t.employee_id
)
select employee_id, jsonb_agg(jsonb_build_object('level', lev, 'id', manager_employee_id, 'terminated_flag', terminated_flag))
from cte
group by employee_id;
Here是db <>小提琴。