一尘不染

Oracle SQL:筛选仅相差很小时间的重复行

sql

我有一个带有事件警报的Oracle表,由于奇怪而未知的情况,有时会重复发生警报,​​因此我被要求创建一个服务,该服务将从该Oracle表中删除重复的警报。

重复考虑一个警报(表中的一行)的条件是,存在另一个具有相同的PKN_EVENTNAME和RECEIVEDDATE的警报,它与前一个仅相差很小的时间(例如10秒,例如-
up或下-)。

我首先要做的是创建一个Oracle sql语句,该语句将按PKN_EVENTNAME将所有警报分组,并在每个组中将重复的警报分开(以供以后删除)。

我想我在路上,但是我被卡住了。

驴有任何帮助吗?

到目前为止,我的SQL:

select t1.ID, t1.PKN_EVENTNAME, t1.RECEIVEDDATE 
from PARQUIMETERS_ALARMS t1 
where 
  exists
     (select 'x' 
      from   PARQUIMETERS_ALARMS t2 
      where  t1.id <> t2.id and                                              -- Not the same row
             trunc(t2.RECEIVEDDATE) = trunc(t1.RECEIVEDDATE)                 -- Same date
             and abs(t1.RECEIVEDDATE - t2.RECEIVEDDATE) * 24 * 60 * 60 < 10)  -- < 10 sec

在此处输入图片说明

编辑1:

通过@Tejash更正,我在Visual Studio Oracle
SQL浏览器中看到了不同的结果,但是我无法理解它们。我不清楚结果是否已经是要删除的记录(重复的警报)还是什么。


阅读 176

收藏
2021-03-08

共1个答案

一尘不染

您可以利用range分析函数的子句:

with dups as (
  select t1.*
       , row_number() over (
           partition by PKN_EVENTNAME, RECEIVEDDATE
           order by id
         ) as dup
  from PARQUIMETERS_ALARMS t1
), nodups as (
  select * from dups where dup = 1
), t as (
  select nodups.ID, nodups.PKN_EVENTNAME, nodups.RECEIVEDDATE
       , count(*) over (
           partition by nodups.PKN_EVENTNAME
           order by nodups.RECEIVEDDATE
           range between interval '10' second preceding and current row
         ) as cnt
  from nodups
)
select * from t where cnt = 1

(已更新:CTE,dups并且nodups在注释中显示的OP之后添加了重复的元组(PKN_EVENTNAME, RECEIVEDDATE)。)

说明:清除通过nodupsCTE传递的数据后,该where条件仅过滤在最近10 s中仅存在单行的行(显然是当前行)。

2021-03-08