如何根据最近的日期在 Oracle table 中保存记录

How to keep records in an Oracle table based on the nearest date

我有一个 Oracle table T,其中有多个记录具有不同的开始日期。我想删除所有内容,但要保留 col1、col2、col3 的相同组合中日期最长的那个。在此示例中,我想保留日期为 2017 年 5 月 31 日的日期并删除其他两个。在不创建另一个分段的情况下在单个查询中实现此目的的最佳方法是什么 table?

测试脚本-

create table t 
(col1 number(10)
,col2 number(10)
,col3 number(10)
,col4 number(10)
,col5 date
);

insert into t values (15731,467,4087,14427,'09-Apr-17');
insert into t values (15731,467,4087,17828,'31-May-17');
insert into t values (15731,467,4087,15499,'16-Apr-17');
commit;

select * from t;[enter image description here][1]

根据以上数据,我只想保留日期为 31-May-17 的记录,因为这是具有相同 col1、col2、col3 组合的最大日期,并删除其余两个关闭 table。请注意,此 table 上还有数百万条其他记录,例如上述记录。 如果这个问题对于 Oracle 专家来说太天真了,我深表歉意,但我是一个非常新的尝试在这个地方使用 Oracle 数据库的人。

您可以按日期与 sysdate 之间的差值的绝对值对行进行排序。然后,您可以使用 rowid 伪列来关联查询和删除语句:

DELETE FROM t
WHERE  rowid NOT IN (SELECT r
                     FROM   (SELECT rowid AS r, 
                                    ROW_NUMBNER() OVER 
                                        (PARTITION BY col1, col2, col3
                                         ORDER BY ABS(SYSDATE - col5) ASC) AS rn
                             FROM   t)
                     WHERE  rn = 1)

由于它被标记为 oracle12c,您不妨利用它的功能。例如,使用 MATCH_RECOGNIZE:

delete from t
  where rowid not in (
                       select rowid
                       from   t
                         match_recognize (
                           partition by col1, col2, col3
                           order by col5 desc
                           all rows per match
                           pattern ( ^ a x* )
                           define x as x.col5 = a.col5
                         )
                     )
;

这假设您希望为给定的 COL1、COL2、COL3 组合保留所有行 "tied" 的最新开始日期。该解决方案可以根据需求的变化进行调整。