简体   繁体   English

使用正确的日期值更新表,而在SQL中没有间隙

[英]Update table with correct date values without gap in sql

I have a table tab_assignment_xx 我有一张桌子tab_assignment_xx

date_from   date_end     action  person_number
01-Apr-2014 31-Jul-2014   HIRE   050498
01-Aug-2014 31-Jan-2015   OTHERS    050498
01-Feb-2015 30-Jun-2015   OTHERS    050498
01-Jul-2015 15-Nov-2015   OTHERS    050498
16-Nov-2015 **31-Dec-4712** OTHERS  050498
01-Jan-2016 **31-Dec-4712** OTHERS  050498

now in this record for employee 050498 there are two dates with 31-dec-12 and a break in the dates. 现在,在该记录中,员工050498的日期是两个日期,分别是12年12月31日和一个休息日。 For example before 01-Jan-16 it should have been 31-dec-2015 and not 31-dec-12. 例如,在16年1月1日之前,应该是2015年12月31日,而不是12月31日。

i want to find such breaks in the entire table. 我想在整个桌子上找到这样的休息时间。

The query : 查询:

select *
  from tab_assignment_xx a 
 where not exists (select 1
                     from tab_assignment_xx b
                    where a.date_end + 1  = b.date_from
                      and a.person_number = b.person_number)
   and a.date_from != (select max(date_from)
                         from tab_assignment_xx c
                        where a.person_number = c.person_number);

But this value i want to update in the table for example the output of the table of the above sample should be something like : 但是这个值我想在表中更新,例如上述示例的表的输出应类似于:

  date_from   date_end     action  person_number
    01-Apr-2014 31-Jul-2014   HIRE   050498
    01-Aug-2014 31-Jan-2015   OTHERS    050498
    01-Feb-2015 30-Jun-2015   OTHERS    050498
    01-Jul-2015 15-Nov-2015   OTHERS    050498
    16-Nov-2015 **31-Dec-2015** OTHERS  050498
    01-Jan-2016 **31-Dec-4712** OTHERS  050498


  update tab_assignment_xx

  set effective_end_date =(select max(date_from)-1
                           from tab_assignment_xx a 
                           where not exists (select 1
                           from tab_assignment_xx b
                           where a.date_end + 1  = b.date_from
                         and a.person_number = b.person_number)
                        and a.date_from != (select max(date_from)
                         from TAB_ASSIGNMENT_XX C
                        where a.person_number = c.person_number));

But this update is not working. 但是此更新无法正常工作。 can anyone give the logic ill try to update the query. 任何人都可以使逻辑错误尝试更新查询。

You can use the analytic lead() function to find the expected end date, as the following start date - 1: 您可以使用analytic lead()函数查找预期的结束日期,如以下开始日期-1:

select t.*,
  lead(date_from) over (partition by person_number order by date_from) - 1 as lead_from
from tab_assignment_xx t;

And you can then use that as the using clause of a merge , wrapped in another layer of select to only find those that are wrong ( lead_from != date_end ), and also to exclude the final record in the sequence, whose lead_from will be null: 然后,您可以将其用作mergeusing子句,包装在select的另一层中,以仅查找错误的内容( lead_from != date_end ),还可以排除序列中的最终记录(其lead_from将为null) :

merge into tab_assignment_xx t
using (
  select * from (
    select t.*,
      lead(date_from) over (partition by person_number order by date_from) - 1 as lead_from
    from tab_assignment_xx t
  )
  where lead_from is not null and date_end != lead_from
) tmp
on (t.date_from = tmp.date_from and t.person_number = tmp.person_number)
when matched then update set t.date_end = tmp.lead_from;

1 row merged.

select * from tab_assignment_xx;

DATE_FROM   DATE_END    ACTION PERSON
----------- ----------- ------ ------
01-Apr-2014 31-Jul-2014 HIRE   050498
01-Aug-2014 31-Jan-2015 OTHERS 050498
01-Feb-2015 30-Jun-2015 OTHERS 050498
01-Jul-2015 15-Nov-2015 OTHERS 050498
16-Nov-2015 31-Dec-2015 OTHERS 050498
01-Jan-2016 31-Dec-4712 OTHERS 050498

Notice, though, that this (and your original query) will close any legitimate gaps - if a person left and was rehired, for example. 但是请注意,这(和您的原始查询)将消除任何合法的空白-例如,如果有人离开并被重新雇用。 You could probably fix that by looking at the action, if necessary. 如有必要,您可以通过查看操作来解决此问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM