Pau*_*lin 6 postgresql recursive-query
我知道答案似乎是根据这篇文章使用"WITH RECURSIVE",但我只是没有得到它.
我有一个叫做的表people,还有一个叫做的表position_hierarchy.该people表具有uperson_id我们调用的唯一ID 和位置ID pcn以及enabled标志(因为当有人离开并被替换时,他们的替换变得相同pcn).在position_hierarchy有柱pcn,以及另一列reports_to这是pcn在层次在他们之上的人.我想要做的是给一个人uperson_id并uperson_id在层次结构中找到他们上面的所有人,和/或给一个uperson_id人和另一个人,uperson_id并告诉第二个人是否具有超过第一个人的监督职位.
公司总裁表示,因为他们pcn和他们一样reports_to.(不是我的决定 - 我会使用null reports_to)
到目前为止我想出的是:
with recursive parents (uperson_id, pcn, reports_to) as
(
select p1.uperson_id, ph1.pcn, ph1.reports_to
from people p1
join position_hierarchy ph1 on ph1.pcn = p1.pcn
where reports_to != ph1.pcn and active_revoke_flag = '0'
union all
select p2.uperson_id, ph2.pcn, ph2.reports_to
from people p2
join position_hierarchy ph2 on p2.pcn = ph2.pcn
join parents pp on pp.pcn = ph2.reports_to
)
select parents.* from parents where uperson_id = 'aaa3644';
Run Code Online (Sandbox Code Playgroud)
但是返回5行,使用相同的uperson_id,pcn和reports_to(这似乎是正确的行数,但我希望每个级别的主管的uperson_id.我觉得我缺少一些非常基本的东西,我可能会打耳光当你告诉我我做错了什么时,我的脑袋.
我做了什么
根据Erwin Brandstetter的回答,我解决了一些问题(主要是因为我没有弄清楚它active_revoke_flag在哪个表格中)并想出了:
with recursive p as (
select pcn, reports_to
from position_hierarchy
where pcn = (SELECT pcn FROM people WHERE uperson_id = 'aaa3644')
union all
select ph2.pcn, ph2.reports_to
from p
join position_hierarchy ph2 ON ph2.pcn = p.reports_to AND
p.pcn != p.reports_to
)
select p2.uperson_id, p2.active_revoke_flag, p.*
from p
join people p2 USING (pcn)
where p2.active_revoke_flag = '0';
Run Code Online (Sandbox Code Playgroud)
我会尝试这种自下而上的方法,从感兴趣的人开始,然后逐步向上:
with recursive p as (
select p1.uperson_id, p1.pcn, ph1.reports_to
from people p1
join position_hierarchy ph1 USING (pcn)
where ph1.active_revoke_flag = '0'
and p1.uperson_id = 'aaa3644'
union all
select p2.uperson_id, p2.pcn, ph2.reports_to
from p
join position_hierarchy ph2 ON ph2.pcn = p.reports_to
AND ph2.active_revoke_flag = '0'
join people p2 ON p2.pcn = ph2.pcn
)
select * from p;
Run Code Online (Sandbox Code Playgroud)
或者,更快,因为我们只加入person一次:
with recursive p as (
select pcn, reports_to
from position_hierarchy
where active_revoke_flag = '0'
and pcn = (SELECT pcn FROM person WHERE uperson_id = 'aaa3644')
union all
select ph2.pcn, ph2.reports_to
from p
join position_hierarchy ph2 ON ph2.pcn = p.reports_to
AND ph2.active_revoke_flag = '0'
)
select p2.uperson_id, p.*
from p
join people p2 USING (pcn); -- assuming pcn is unique in table person
Run Code Online (Sandbox Code Playgroud)
顺便说一句:我确实发现你的设计重复pcn有点可疑。
| 归档时间: |
|
| 查看次数: |
747 次 |
| 最近记录: |