Сравнение результатов предыдущего запроса в рекурсивном запросе - PullRequest
0 голосов
/ 14 июля 2020

Я настроил запрос, чтобы найти самый ранний раз, когда человек X был повышен до определенного c ранг-

"firsttimeEMplus" AS (
    SELECT MIN(ra."EffectiveDate")
    FROM rankachievement ra
    WHERE ra."NewRank" IN ('Executive Manager', 
         'Associate Director', 
         'Director', 
         'Senior Director', 
         'Executive Director', 
         'Managing Director'))

Теперь я хотел бы использовать результат этого запроса как часть инструкции CASE в моем рекурсивном запросе, где я выясняю, был ли человек X повышен до своего родителя. Итак, где дочерний элемент firsttimeEMplus

SELECT (CASE WHEN (**child**"firsttimeEMplus" <= **parent**"firsttimeEMplus) THEN etc....

Но я не понимаю, какой синтаксис позволяет мне сравнивать родительский элемент с дочерним таким образом, или могу ли я даже сделать что-то подобное в СЛУЧАЕ заявление. Если бы кто-нибудь мог предоставить руководство или ресурсы или где я мог бы найти примеры того, как это может работать, я был бы очень признателен. Спасибо!

1 Ответ

0 голосов
/ 15 июля 2020

Это без рекурсии.

Идея состоит в том, чтобы получить список всех ваших людей с их first_time_em датой. Использование предложений left join и filter вернет всех людей, независимо от того, достигли ли они когда-либо уровня EM.

Присоедините этот результат обратно к самому себе, соединяя каждую запись с ее родительской записью. Опять же, это left join, поскольку человек на вершине иерархии не должен иметь родителя.

Оператор case может быть просто boolean сравнением с coalesce, поскольку все, что нам нужно, это true / false. Возможные условия:

  1. Детский first_time_em перед родительским first_time_em, что дает true
  2. У ребенка first_time_em, а у босса нет (null), которое coalesce() превращается в 9999-12-31, что дает true
  3. У ребенка нет first_time_em (null), дает false по else
  4. Детский first_time_em находится после родительского first_time_em, дает false по 'else`
  5. Ни у ребенка, ни у родителя нет first_time_em, дает false по else
with person_achievement as (
  select p.person_id, p.parent_id, 
         MIN(ra."EffectiveDate") 
           filter (when ra."NewRank" in 
             ('Executive Manager', 'Associate Director', 'Director', 
              'Senior Director', 'Executive Director', 'Managing Director')
           ) as first_time_em
    from person p
    left join rankachievement ra 
      on ra.person_id = p.person_id
)
select pc.*, 
       case
         when pc.first_time_em < coalesce(pp.first_time_em, '9999-12-31') then true
         else false
       end as made_em_before_boss
  from person_achievement pc
  left join person_achievement pp
    on pp.person_id = pc.parent_id
;
...