oraclesql:过滤只相差很小时间的重复行

8dtrkrch  于 2021-07-24  发布在  Java
关注(0)|答案(3)|浏览(342)

我有一个带有事件警报的oracle表,由于一个奇怪的未知条件,警报有时会重复出现,所以我被要求创建一个服务,从oracle表中删除重复的警报。
将报警(表中的一行)视为重复的条件是,另一个报警具有相同的pkn\u eventname和receiveddate,但与前一个报警仅在很短的时间内不同(例如,10秒-向上或向下-)。
我首先要做的是创建一个oraclesql语句,它将根据pkn\u 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更正,我在visualstudiooraclesql浏览器中看到了不同的结果,但我不能理解它们。我不清楚结果是否已经是要删除的记录(重复报警)或什么。

nnsrf1az

nnsrf1az1#

你可以利用 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

(更新:ctes) dups 以及 nodups 在注解中显示的op之后添加了重复元组 (PKN_EVENTNAME, RECEIVEDDATE) .)
说明:清除通过的数据后 nodups cte公司 where 条件只筛选在过去10秒内只有一行的行(显然是当前行)。

xggvc2p6

xggvc2p62#

你失踪了 t1.PKN_EVENTNAME = t2.PKN_EVENTNAME 在你的 exists 在你的生活中有一个不相关的情况 exists 条款。
您的查询应如下所示:

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   -- Not the same row                                         
             --trunc(t2.RECEIVEDDATE) = trunc(t1.RECEIVEDDATE)   -- this is not needed
             and t1.PKN_EVENTNAME = t2.PKN_EVENTNAME -- added this
             and abs(t1.RECEIVEDDATE - t2.RECEIVEDDATE) * 24 * 60 * 60 < 10) -- < 5 sec
hs1rzwqc

hs1rzwqc3#

你当然可以用 exists . 然而,使用解析函数可能更有效。像这样的

with alarms as (
  select pa.*,
         lag(pa.RECEIVEDDATE) over (partition by pa.pkn_eventName
                                        order by pa.recievedDate) prior_receivedDate
    from PARQUIMETERS_ALARMS pa
)
select *
  from alarms
 where receivedDate - prior_receivedDate <= interval '10' second;

注意,我把 alarms 子查询,这样您就可以轻松地单独运行它,并查看带有附加 prior_receivedDate 在应用筛选条件查找重复行之前。这通常在调试/可视化数据时非常有用。但是如果对您来说更容易的话,您可以自由地使用内联视图编写查询。

相关问题