この投稿のとおり、答えは「WITH RECURSIVE」を使用するように思われることはわかっていますが、うまくいきません。
と呼ばれるpeople
テーブルと。と呼ばれるテーブルがありますposition_hierarchy
。people
テーブルには、私たちが呼び出す一意のIDとuperson_id
位置ID、pcn
およびenabled
フラグがあります(誰かが離れて置き換えられた場合、それらの置き換えは同じになるためpcn
)。にはposition_hierarchy
列があり、階層内でその上の人の列であるpcn
別の列があります。私がやりたいのは、ある人を与えて、階層内でその上の人のすべてを見つけること、および/または他の人を与えて、2番目の人が最初の人よりも監督的な立場にあるかどうかを伝えることです。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';
しかし、それは同じuperson_id、pcn、reports_toで5行を返します(これは正しい行数のようですが、各レベルでスーパーバイザーの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';