日期重叠的记录

时间:2016-02-25 17:05:09

标签: sql oracle

我有一张地址表,说:

address_id  person_id  start_date  stop_date  address 
         1        123  01-JAN-15   01-JUN-15  india 
         2        123  01-MAY-15   null       russia 
         3        321  01-JAN-15   01-JUN-15  us
         4        321  10-MAY-15   null       india

我想查找所有记录(address_id值),这些记录具有相同person_id的重叠日期。在这个例子中会找到address_id 2和4,因为May位于Jan和Jun之间。

然后,我想要更新属于同一个人的后续行的stop_datestart_date - 1,以便删除重叠。例如,将stop_date更新为2015年5月9日at row with地址_id` 3。

所以我想最终:

address_id  person_id  start_date  stop_date  address
         1        123 01-JAN-15  30-APR-15    india
         2        123 01-MAY-15  null         russia
         3        321 01-JAN-15  09-MAY-15    us
         4        321 10-MAY-15  null         india

我试过了:

update (
select * from addresses a1,addresses a2
where a1.person_id = a2.person_id
and a2.start_date > a1.start_date and a2.start_date <a1.stop_date
)
set a1.stop_date = a2.start_date - 1;

这在Microsoft Access中运行良好,但在Oracle中,a2.start_date无效标识符错误。

如何执行此更新?

1 个答案:

答案 0 :(得分:1)

您可以使用相关更新:

update addresses a
set stop_date = (
  select min(start_date) - 1
  from addresses
  where person_id = a.person_id
  and start_date > a.start_date
  and start_date <= a.stop_date
)
where exists (
  select null
  from addresses
  where person_id = a.person_id
  and start_date > a.start_date
  and start_date <= a.stop_date
);

2 rows updated.

select * from addresses;

ADDRESS_ID  PERSON_ID START_DATE STOP_DATE ADDRESS  
---------- ---------- ---------- --------- ----------
         1        123 01-JAN-15  30-APR-15 india     
         2        123 01-MAY-15            russia    
         3        321 01-JAN-15  09-MAY-15 us        
         4        321 10-MAY-15            india     

set子查询和exists子查询都为同一个人查找一行,其开始日期在当前行的开始日期和停止日期之间(相关部分)。 exists表示只更新匹配的帐户;没有这个,任何没有重叠的行都会更新为null。 (您不会看到样本数据有任何差异,但如果您有更多数据,则会有所不同。)