在sql中更新具有正确日期值的表,没有间隙

时间:2016-03-21 16:43:16

标签: sql oracle

我有一个表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

现在在员工050498的这个记录中有两个日期,31-dec-12和日期中断。例如,在01年1月1日之前,它应该是2015年12月31日,而不是31-dec-12。

我想在整个表格中找到这样的休息时间。

查询:

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);

但是这个值我想在表格中更新,例如上面示例表格的输出应该是这样的:

  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));

但此更新无效。任何人都可以尝试更新查询。

1 个答案:

答案 0 :(得分:2)

您可以使用分析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;

然后,您可以将其用作using的{​​{1}}子句,包含在另一个select层中,以便仅查找错误的merge},并排除序列中的最终记录,其lead_from != date_end将为null:

lead_from

但请注意,这个(以及您的原始查询)将关闭任何合法的间隙 - 例如,如果一个人离开并被重新雇用。如有必要,你可以通过查看动作来解决这个问题。