【问题标题】:SQL Query to get number of times and duration of a column values reaches a specific value in a sequenceSQL 查询以获取列值达到序列中特定值的次数和持续时间
【发布时间】:2014-06-17 00:51:36
【问题描述】:

我有一个包含两列 ReceivedOn(Date/Time) 和 Speed(int) 的表格 示例数据如下所示

     ReceivedOn       |   Speed
 ----------------------------------------------
 2012-11-05 06:30:00          10
 2012-11-05 06:31:00          45
 2012-11-05 06:32:00          48
 2012-11-05 06:33:00          53
 2012-11-05 06:34:00          47
 2012-11-05 06:35:00          38
 2012-11-05 06:36:00          22
 2012-11-05 06:37:00          36
 2012-11-05 06:38:00          41
 2012-11-05 06:39:00          47
 2012-11-05 06:40:00          49
 2012-11-05 06:41:00          22
 2012-11-05 06:42:00          36

我需要在速度 > 40 时对行进行分组,以便生成的输出为

       StartTime      |   EndTime               |  Count
 --------------------------------------------------------
 2012-11-05 06:31:00     2012-11-05 06:34:00         4
 2012-11-05 06:38:00     2012-11-05 06:40:00         3

StartTime 为速度第一次超过 40 时的 ReceivedOn 值,EndTime 值为连续超过 40 条时的 ReceivedOn 值,其中 Count 为连续超过 40 条记录的总数。

我尽了最大的努力,但无法得到它。是否有可能通过 sql 查询得到这个? 请建议。提前致谢。

【问题讨论】:

  • 我真的不明白这个问题,你能详细说明你想要达到的目标吗?谢谢
  • 如果我理解正确,他希望StartTime 成为速度第一次超过 40 时的 ReceivedOn 值,而 EndTime 值是最后超过 40 英寸时的 ReceivedOn 值连续记录,Count 是超过 40 条连续记录的总数。
  • 正如@Siyual 所说。我已经编辑了我的问题。
  • 另外,发布您尝试过的内容。所以,谁知道你不是要我们做功课呢。
  • 你有时间间隔吗?还是每分钟都有代表?如果有差距,在输出结果集中应该如何处理?

标签: mysql sql


【解决方案1】:

以下是此类问题的一般答案。 Detect consecutive items meeting particular criteria in a time series

您的具体情况似乎更容易,因为您没有时间间隔(他希望如此说)。你正试图在你的时间序列中找到差距。在您的情况下,间隙被定义为 >= 40 的那些项目。因此,您正在寻找值小于 40 的事件序列中的间隙。

这是一个查询,它使用行号为您提供时间序列。

SELECT @RowA := @RowA + 1 AS ROWNUM,
       ReceivedOn, Speed
   FROM (
        SELECT ReceivedOn, Speed
          FROM obs
         WHERE NOT Speed >= 40
   ) AS A
   JOIN (SELECT @RowA := 0) AS B

现在您使用一些严肃的 SQL 猴子业务将这个序列自我加入到自身中。像这样工作:

SELECT B.ReceivedON + INTERVAL 1 MINUTE As StartTime,
       A.ReceivedOn - INTERVAL 1 MINUTE AS EndTime,
       -1 + TIMESTAMPDIFF(MINUTE, B.ReceivedOn, A.ReceivedOn) AS Count
  FROM (
         SELECT @RowA := @RowA + 1 AS ROWNUM,
                ReceivedOn, Speed
           FROM (
              SELECT ReceivedOn, Speed
                FROM obs
               WHERE NOT Speed >= 40
                ) AS A
           JOIN (SELECT @RowA := 0) AS B
       ) AS A
  JOIN (
          SELECT @RowB := @RowB + 1 AS ROWNUM,
                 ReceivedOn, Speed
         FROM (
              SELECT ReceivedOn, Speed
                FROM obs
               WHERE NOT Speed >= 40
              ) AS A
         JOIN (SELECT @RowB := 0) AS B
        ) AS B ON B.ROWNUM+1 = A.ROWNUM
 WHERE TIMESTAMPDIFF(MINUTE, B.ReceivedOn, A.ReceivedOn) > 1

http://sqlfiddle.com/#!2/2cb57/24/0

这看起来很麻烦,但它只是第一个查询与自身ON B.ROWNUM+1 = A.ROWNUM 的连接。这会将查询的结果集与自身偏移一行对齐,因此您可以比较连续的行。

这给出了您需要的结果。请注意,如果您的第一个观察值 >= 40,则此查询将忽略第一个观察序列。

【讨论】:

  • 谢谢@Ollie Jones。但遗憾的是,记录之间的时间间隔并不固定。它可以是几秒钟、几分钟或几小时。否则这将是一个很好的解决方案。我必须在样本数据中找到每次超过某个 x 限制的速度,比如 40。该事件的开始时间和结束时间。
猜你喜欢
  • 2022-01-12
  • 2018-08-27
  • 1970-01-01
  • 2020-09-14
  • 2021-06-30
  • 2017-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多