2017-07-14 16 views
0

我有一个表foo与列id(不唯一),start_dateend_date。我想,对于具有某个id的所有行,没有[start_date,end_date)范围重叠。我想通过更改有问题的行的end_date来做到这一点。如何将范围更新为不重叠?

update foo old 
set end_date = new.start_date 
from foo new 
where old.start_date < new.start_date and old.end_date > new.start_date 
and old.id = new.id and new.id = 8675309; 

然而,这不会如果old重叠多个其他记录工作。我的最佳尝试是

update foo old 
set end_date = (select coalesce(min(new.start_date), old.end_date) 
    from foo new 
    where old.start_date < new.start_date and old.end_date > new.start_date 
    and new.id = old.id) 
where old.id = 8675309; 

这可行,但它不必要地更新每一行,感觉就像一个黑客。什么是最好的方法来做到这一点?

回答

0

此假设start_date是内id

update foo 
set end_date = s.lsd 
from (
    select 
     id, start_date, 
     lead (start_date, 1, end_date) over (
      partition by id order by start_date 
     ) as lsd 
    from foo 
) s 
where 
    foo.id = s.id and 
    foo.start_date = s.start_date and 
    foo.end_date > s.lsd 
独特