如何按时间采样记录

Sam*_*Axe 7 sql-server t-sql sql-server-2014

所以我在 SQL Server 2014 中有一个存储事件的表。事件的生成速度不超过每 10 秒一次,但可能会慢得多(事件之间的几分钟或几小时)。事件之间的时间并不统一。

我想按时间对记录进行抽样。
例如,我想要求一个 10 分钟的采样 - 所以它会抓取记录 1,下一条记录应该是至少 10 分钟后的记录,然后下一条记录至少比第 2 行晚 10 分钟, 等等。

我可以通过迭代方法来实现这一点,循环遍历每条记录,但我想让数据库来完成这项工作。问题是,我不知道如何使用 T-SQL set/window 语句来做到这一点。

谁能帮我吗?

示例数据:

EventID | RecordTime
--------+--------------------
   1    | 2017-04-01 12:00:00
   2    | 2017-04-01 12:00:10
   3    | 2017-04-01 12:00:20
   4    | 2017-04-01 12:00:32
   5    | 2017-04-01 12:05:42
   6    | 2017-04-01 12:09:00
   7    | 2017-04-01 12:24:12
   8    | 2017-04-01 12:36:46
   9    | 2017-04-01 12:36:57
  10    | 2017-04-01 15:00:00
Run Code Online (Sandbox Code Playgroud)

想要的结果:

EventID | RecordTime
--------+--------------------
   1    | 2017-04-01 12:00:00
   7    | 2017-04-01 12:24:12
   8    | 2017-04-01 12:36:46
  10    | 2017-04-01 15:00:00
Run Code Online (Sandbox Code Playgroud)
  • EventID 2-6 都在记录 1 的 10 分钟内,所以我不想要它们。
  • EventID 7 比我的结果集中的最后一条记录 (EventID 1) 晚 24 分 12 秒,所以我确实想要它。
  • EventID 8 比我的结果集中的最后一条记录 (EventID 7) 晚 12 分 34 秒,所以我确实想要它。
  • EventID 9 比我的结果集中的最后一条记录 (EventID 8) 晚 11 秒,所以我不想要它。
  • EventID 10 是 apx。比我的结果集中的最后一条记录 (EventID 9) 晚 2.5 小时,所以我确实想要它。

Vla*_*nov 4

如果您不想在 处发生事件12:10:01,那么答案非常简单 - 使用LEADLAG来比较两个连续行的时间戳。请注意,如果您有一长串事件,其中每对事件相隔不到 10 分钟,则查询将仅返回该序列的第一个事件。

换句话说,两个事件之间必须有超过 10 分钟的间隔才能将行添加到结果集中。

样本数据

DECLARE @T TABLE(EventID int, RecordTime datetime2(0));
INSERT INTO @T (EventID, RecordTime) VALUES
( 1, '2017-04-01 12:00:00'),
( 2, '2017-04-01 12:00:10'),
( 3, '2017-04-01 12:00:20'),
( 4, '2017-04-01 12:00:32'),
( 5, '2017-04-01 12:05:42'),
( 6, '2017-04-01 12:09:00'),
( 7, '2017-04-01 12:24:12'),
( 8, '2017-04-01 12:36:46'),
( 9, '2017-04-01 12:36:57'),
(10, '2017-04-01 15:00:00');
Run Code Online (Sandbox Code Playgroud)

询问

WITH
CTE
AS
(
    SELECT
        EventID
        ,RecordTime
        ,LAG(RecordTime) OVER (ORDER BY EventID) AS PrevRecordTime
    FROM @T
)
SELECT
    EventID
    ,RecordTime
FROM
    CTE
    CROSS APPLY
    (
        SELECT DATEDIFF(second, PrevRecordTime, RecordTime) AS RecordDiffSeconds
    ) AS CA
WHERE
    RecordDiffSeconds IS NULL
    OR RecordDiffSeconds > 600
ORDER BY EventID;
Run Code Online (Sandbox Code Playgroud)

结果

+---------+---------------------+
| EventID |     RecordTime      |
+---------+---------------------+
|       1 | 2017-04-01 12:00:00 |
|       7 | 2017-04-01 12:24:12 |
|       8 | 2017-04-01 12:36:46 |
|      10 | 2017-04-01 15:00:00 |
+---------+---------------------+
Run Code Online (Sandbox Code Playgroud)