PL SQL 查找某个时间段内的重复事件

Posted

技术标签:

【中文标题】PL SQL 查找某个时间段内的重复事件【英文标题】:PL SQL Find repeat events within a time period 【发布时间】:2014-11-14 15:51:03 【问题描述】:

提前致谢。

我有一个具有以下架构的表

CallNotes (
Policy    VARCHAR2(15 BYTE)
Notes_TS  TIMESTAMP(6)
UserId    VARCHAR2(50 BYTE)
)

此表的粒度是通话中发生的每个事件的记录。为了识别重复呼叫,我需要查找具有相同策略的下一个时间戳,但在未来 10 分钟到 7 天之间发生了不同的用户 ID。 7 天后发生的任何事情都将是一个新呼叫。

Policy 和 UserID 可以用新的 note_ts 重复,例如:

Policy   |Notes_TS                 |UserId
123abc   |2014-11-14 10:10:05.000  |joe
123abc   |2014-11-14 10:11:32.000  |joe
123abc   |2014-11-14 10:11:55.000  |joe
156def   |2014-11-14 10:15:16.000  |julie
123abc   |2014-11-14 10:23:42.000  |jane

因此,123abc 调用了两次,因为它是一个重复的策略,具有不同的用户 ID,未来 10 分钟以上。

我打算使用 CTE 和窗口函数来完成此任务,但我无法完成第一步。

我的查询看起来像这样,我尝试了分区的变体,但是,我只是没有正确考虑这个问题。

With orderedCalls as 
    ( Select 
        Policy,
        UserId,
        Notes_TS NewCallTime,
        lag(Notes_TS,1,'01-JAN-1900') over (partition by Policy, UserId order by Notes_TS) prev_ts,
        lead(Notes_TS,1,'01-JAN-1900') over (partition by Policy, UserId order by Notes_TS) prev_ts
        row_number() over(partition by Policy order by Notes_ts) "Order"
      From CallHistory),
  RepeatCalls as 
    (.....

我也在考虑通过策略和策略、用户 ID 以及使用它来获得行排序。

谢谢。

【问题讨论】:

【参考方案1】:

您可以使用lag() 函数获取有关上一次调用的时间戳的信息:

select cn.*,
       (case when prev_userid <> userid and
                  notes_ts - prev_ts between '+00 00:10:00' and '+07 00:00:00'
              then 1 else 0 end) as IsRepeat
from (select cn.*,
             lag(Notes_ts) over (partition by Policy order by Notes_ts) as prev_ts,
             lag(userid) over (partition by Policy order by Notes_ts) as prev_userid
      from CallNotes cn
     ) cn;

【讨论】:

谢谢。这很好,除了它抓取下一个条目,而不是来自不同用户的下一个条目。我用示例数据编辑了我的问题。很抱歉造成混乱。 @StephenLloyd 。 . .它抓取下一个条目,然后检查它是否来自同一用户。这听起来仍然像您想要做的,它会在您的示例表中选择第三行。 确实如此。谢谢。我想错了方向。到目前为止看起来不错。

以上是关于PL SQL 查找某个时间段内的重复事件的主要内容,如果未能解决你的问题,请参考以下文章

PL/SQL 函数返回日期之间的数据

Haversine 公式单元错误 - PL/SQL

SQL查询某个时间段内的8-9点的数据

使用 oracle SQL 查找日期范围内的星期几

如何在 PL / SQL 中读取另一个游标内的游标

如何在 PL/SQL 中使用包内的过程