如果一列值没有更改,则SQL查询将获取最旧的start_date



我有一个包含以下列的表per_all_assignments_m-

每个分配(_A(

Person_id    position_id   system_person_type   start_date          END_DT     
1             1             EMP                01-JAN-2019        20-JAN-2019
1             1             EMP                21-JAN-2019        31-DEC-4712
2             1             EMP                01-JAN-2019        03-JUL-2019
2             1             EMP                04-JUL-2019        08-SEP-2019
2             2             EMP                09-SEP-2019        31-DEC-2019 
2             2             EMP                01-JAN-2020        31-DEC-4712
3             10             EMP                01-JAN-2019        20-JAN-2019  
3             10             EMP                21-JAN-2019        08-SEP-2019
3             10             EMP                09-SEP-2019       20-JAN-2020
3             10             EMP                21-JAN-2020       31-DEC-4712

如果position_id列中有任何值更改,我已经创建了下面的查询来获取。此查询将获取更改日期的日期和上一个开始日期。

select person_id, prev_start_dt, effective_start_date current_start_dt,
case pos_new when pos_old then 1 else pos_old end pos_old
from (
select person_id, position_id pos_new, effective_start_date, effective_end_date,
lag(position_id) over (partition by person_id order by effective_start_date) pos_old,
lag(effective_start_date) over (partition by person_id order by effective_start_date) prev_start_dt, 
case effective_start_date when 1 + lag(effective_end_date) over (partition by person_id order by effective_start_date) 
then 1 end flag
from per_all_assignments_m
where person_id=1
and assignment_type = 'E')
where flag = 1 and (pos_new <> pos_old )

对于上表,此查询将获取员工#2的09-SEP-2019作为current_start_dt,获取04-JUL-2019作为prev_start_dt

Question-

现在,我想添加一个条件,如果position_id值没有变化,那么应该检索最旧的effective_start_date。

示例-对于EE#1,current_start_dt应为2019年1月1日,prev_start_dt应与EE#3相同,current_start _dt和prev_start _dt应为2019年1月1日。

任何建议都会有很大帮助!

所需输出-

Person_id            prev_start_dt                 current_start_dt                 pos_old
1                      01-JAN-2019                    01-JAN-2019                    1
2                       04-JUL-2019                   09-SEP-2019                    1
3                       01-JAN-2019                   01-JAN-2019                    10

这里有一种方法:

cte2获取有更改的person_id,结果是person_id行,并添加第一次出现的没有更改的person_id

Fiddle

with cte as
(                     
select 1     as Person_id,        1     as position_id,        'EMP'      as system_person_type,          STR_TO_DATE('01-JAN-2019', "%d-%M-%Y")  as start_date,     STR_TO_DATE('20-JAN-2019', "%d-%M-%Y") as END_DT
union select 1,             1 ,            'EMP' ,               STR_TO_DATE('21-JAN-2019', "%d-%M-%Y"),        STR_TO_DATE('31-DEC-4712', "%d-%M-%Y")
union select 2 ,            1  ,           'EMP'  ,              STR_TO_DATE('01-JAN-2019', "%d-%M-%Y") ,       STR_TO_DATE('03-JUL-2019', "%d-%M-%Y")
union select 2  ,           1   ,          'EMP'   ,             STR_TO_DATE('04-JUL-2019', "%d-%M-%Y")  ,      STR_TO_DATE('08-SEP-2019', "%d-%M-%Y")
union select 2   ,          2    ,         'EMP'    ,            STR_TO_DATE('09-SEP-2019', "%d-%M-%Y")   ,     STR_TO_DATE('31-DEC-2019' , "%d-%M-%Y")
union select 2    ,         2     ,        'EMP'     ,           STR_TO_DATE('01-JAN-2020', "%d-%M-%Y")    ,    STR_TO_DATE('31-DEC-4712', "%d-%M-%Y")
union select 3     ,        10     ,        'EMP'     ,           STR_TO_DATE('01-JAN-2019', "%d-%M-%Y")    ,    STR_TO_DATE('20-JAN-2019'  , "%d-%M-%Y")
union select 3      ,       10      ,       'EMP'      ,          STR_TO_DATE('21-JAN-2019', "%d-%M-%Y")     ,   STR_TO_DATE('08-SEP-2019', "%d-%M-%Y")
union select 3       ,      10       ,      'EMP'       ,         STR_TO_DATE('09-SEP-2019', "%d-%M-%Y")      , STR_TO_DATE('20-JAN-2020', "%d-%M-%Y")
union select 3        ,     10        ,     'EMP'        ,        STR_TO_DATE('21-JAN-2020', "%d-%M-%Y")       ,STR_TO_DATE('31-DEC-4712', "%d-%M-%Y");
),
cte2 as 
(
select a.Person_id,  ( (b.start_date)) as prev_start_dt,  (a.start_date) as current_start_dt, (b.position_id) 
from cte a left join cte b on a.Person_id = b.Person_id and a.start_date >  b.start_date and a.position_id <> b.position_id
and not exists(select 1 from cte c where a.Person_id = c.Person_id and a.start_date >  c.start_date and c.start_date >  b.start_date)
)
select Person_id, prev_start_dt, current_start_dt, position_id from cte2 where position_id is not null
union
select a.Person_id, a.start_date, a.start_date, a.position_id from cte a where not exists(select 1 from cte b where a.Person_id = b.Person_id and a.start_date > b.start_date)
and a.Person_id not in (select Person_id from cte2 where position_id is not null)

Output:
Person_id   prev_start_dt   current_start_dt    position_id
1            2019-01-01        2019-01-01        1
2            2019-07-04        2019-09-09        1
3            2019-01-01        2019-01-01        10

如果您想跟踪仓位ID发生变化的所有情况,下面这样的方法应该有效:

with cte as
(                     
select 1 as Person_id,1 as position_id,'EMP' as system_person_type,cast('01Jan2019' as date) as Start_date,cast('20Jan2019' as date) as end_dt from dual union
select 1 as Person_id,1 as position_id,'EMP' as system_person_type,cast('21Jan2019' as date) as Start_date,cast('31Dec4712' as date) as end_dt from dual union
select 2 as Person_id,1 as position_id,'EMP' as system_person_type,cast('01Jan2019' as date) as Start_date,cast('03Jul2019' as date) as end_dt from dual union
select 2 as Person_id,1 as position_id,'EMP' as system_person_type,cast('04Jul2019' as date) as Start_date,cast('08Sep2019' as date) as end_dt from dual union
select 2 as Person_id,2 as position_id,'EMP' as system_person_type,cast('09Sep2019' as date) as Start_date,cast('31Dec2019' as date) as end_dt from dual union
select 2 as Person_id,2 as position_id,'EMP' as system_person_type,cast('01Jan2020' as date) as Start_date,cast('31Dec4712' as date) as end_dt from dual union
select 3 as Person_id,10 as position_id,'EMP' as system_person_type,cast('01Jan2019' as date) as Start_date,cast('20Jan2019' as date) as end_dt from dual union
select 3 as Person_id,10 as position_id,'EMP' as system_person_type,cast('21Jan2019' as date) as Start_date,cast('08Sep2019' as date) as end_dt from dual union
select 3 as Person_id,10 as position_id,'EMP' as system_person_type,cast('09Sep2019' as date) as Start_date,cast('20Jan2020' as date) as end_dt from dual union
select 3 as Person_id,10 as position_id,'EMP' as system_person_type,cast('21Jan2020' as date) as Start_date,cast('31Dec4712' as date) as end_dt from dual
)
select x.Person_Id,
COALESCE(x.lag_start,x.min_date) as Prev_start_dt,
x.min_date as Current_Start_Dt,
COALESCE(x.lag_pos,x.position_id) as Pos_old
FROM
(select person_id, 
position_id,       
min(start_date) as min_date, 
max(start_date) as max_date, 
lag(max(start_date)) Over(Partition by Person_Id Order by max(start_date)) as lag_start,
lag(position_id) Over(Partition by Person_Id Order by min(start_date)) as lag_pos
from cte
group by person_id, position_id) x
inner join
(select person_id,
count(distinct position_id) as cnt
from cte
group by person_id) y
ON x.person_id=y.person_id
Where x.Position_id<>x.lag_pos or y.cnt=1

这个想法是在个人和职位级别上对信息进行分组,然后使用滞后函数来确定是否有变化。应用Cnt=1滤波器来获得没有位置变化的情况。希望这能有所帮助。

相关内容

  • 没有找到相关文章

最新更新