Oracle - присоединиться к последнему статусу во время активности - PullRequest
1 голос
/ 02 апреля 2019

У меня есть две таблицы - одна с активностью сотрудника, а другая с employee_status.Проблема в том, что статус сотрудника меняется со временем, поэтому мне нужно присоединиться к статусу, который был во время сеанса.

>>> employee_activity

    id     session_start
    emp1    1/1/2019
    emp1    2/22/2019
    emp1    3/1/2019
    emp2    1/4/2019
    emp2    2/23/2019

>>> employee_status     

id   status effective date
emp1    a   1/1/2018
emp1    b   2/1/2019
emp1    c   3/5/2019
emp2    a   6/1/2018
emp2    b   1/1/2019

Поэтому я начал писать что-то, что после игнорирования статусов будетактивность, но я немного борюсь с выяснением, как выбрать только самый последний статус.Запрос должен объединять только статус с максимальной датой вступления в силу, которая меньше начала сеанса

    SELECT * FROM employee_activity a
    LEFT join employee_status s on a.id = s.id WHERE s.effective_date <= a.session_start
-- how do I join only the most recent status?

. Желаемым выводом из двух таблиц выше будет

>>> my_output       
id  session_start   status
emp1    1/1/2019    a
emp1    2/22/2019   b
emp1    3/1/2019    b
emp2    1/4/2019    b
emp2    2/23/2019   b

Спасибо !!

Ответы [ 2 ]

2 голосов
/ 02 апреля 2019

Сначала вычислите интервал действия из STATUS, т.е. вместо EFFECTIVE_DATE у вас есть начальная и конечная временная метка.

Обратите внимание, что я использую открытую дату окончания по умолчанию и вычитаю одну секунду из конечной даты, чтобы получить закрытый интервал, который можно запросить, используя BETWEEN.

Чем простое соединение на ключеи добавьте промежуточное ограничение для времени:

with emp as (
select ID, STATUS, EFFECTIVE_DATE status_valid_from,
lead(EFFECTIVE_DATE - INTERVAL '1' SECOND,1,DATE'2500-01-01') 
    over (partition by id order by EFFECTIVE_DATE) as status_valid_to
from employee_status)
SELECT a.id, a.SESSION_START, s.STATUS, s.STATUS_VALID_FROM 
FROM employee_activity a
LEFT join emp s 
on a.id = s.id and  session_start between s.status_valid_from and s.status_valid_to
order by 1,2;

ID   SESSION_START       S STATUS_VALID_FROM  
---- ------------------- - -------------------
emp1 01.01.2019 00:00:00 a 01.01.2018 00:00:00
emp1 22.02.2019 00:00:00 b 01.02.2019 00:00:00
emp1 01.03.2019 00:00:00 b 01.02.2019 00:00:00
emp2 04.01.2019 00:00:00 b 01.01.2019 00:00:00
emp2 23.02.2019 00:00:00 b 01.01.2019 00:00:00

Пример данных

create table employee_activity as 
select    'emp1' id,     to_date('1/1/2019','mm/dd/yyyy') session_start from dual union all 
select    'emp1' id,     to_date('2/22/2019','mm/dd/yyyy') session_start from dual union all 
select    'emp1' id,     to_date('3/1/2019','mm/dd/yyyy') session_start from dual union all 
select    'emp2' id,     to_date('1/4/2019','mm/dd/yyyy') session_start from dual union all 
select    'emp2' id,     to_date('2/23/2019','mm/dd/yyyy') session_start from dual;

create table  employee_status  as     
select 'emp1' id, 'a'status, to_date('1/1/2018','mm/dd/yyyy') effective_date from dual union all 
select 'emp1' id, 'b'status, to_date('2/1/2019','mm/dd/yyyy') effective_date from dual union all 
select 'emp1' id, 'c'status, to_date('3/5/2019','mm/dd/yyyy') effective_date from dual union all 
select 'emp2' id, 'a'status, to_date('6/1/2018','mm/dd/yyyy') effective_date from dual union all 
select 'emp2' id, 'b'status, to_date('1/1/2019','mm/dd/yyyy') effective_date from dual;
0 голосов
/ 02 апреля 2019

Вы можете сделать это, используя коррелированный подзапрос:

select ea.*,
       (select max(es.status) keep (dense_rank first order by es.effective_date desc)
        from employee_status es
        where es.id = ea.id and es.effective_date <= ea.session_start
       ) as status
from employee_activity ea;

В Oracle 12C + есть более интуитивный:

select ea.*,
       (select es.status
        from employee_status es
        where es.id = ea.id and es.effective_date <= ea.session_start
        order by es.effective_date desc
        fetch first 1 row only
       ) as status
from employee_activity ea;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...