当前位置: 首页 > 面试题库 >

在MySQL中找到时间序列数据中的缺口的方法?

微生昌胤
2023-03-14
问题内容

假设我们有一个包含两列的数据库表,entry_time和value。entry_time是时间戳记,而value可以是任何其他数据类型。记录是相对一致的,大约每隔x分钟输入一次。但是,对于许多x的时间来说,可能无法进行输入,从而在数据中产生“间隙”。

在效率方面,如何通过查询找到至少Y时间(新旧)之间的差距的最佳方法是什么?


问题答案:

首先,让我们按小时汇总表中的条目数。

SELECT CAST(DATE_FORMAT(entry_time,'%Y-%m-%d %k:00:00') AS DATETIME) hour,
       COUNT(*) samplecount
  FROM table
 GROUP BY CAST(DATE_FORMAT(entry_time,'%Y-%m-%d %k:00:00') AS DATETIME)

现在,如果您每六分钟(每小时十次)记录一次,则所有samplecount值应为十。此表达式:CAST(DATE_FORMAT(entry_time,'%Y-%m-%d %k:00:00') AS DATETIME)看起来很毛茸茸,但只需将分钟和秒清零,就可以将时间戳截短到出现的小时。

这是相当有效的,并且可以帮助您入门。如果您可以在entry_time列上放置索引并将查询限制为昨天的示例(如此处所示),那将非常有效。

SELECT CAST(DATE_FORMAT(entry_time,'%Y-%m-%d %k:00:00') AS DATETIME) hour,
       COUNT(*) samplecount
  FROM table
 WHERE entry_time >= CURRENT_DATE - INTERVAL 1 DAY
   AND entry_time < CURRENT_DATE
 GROUP BY CAST(DATE_FORMAT(entry_time,'%Y-%m-%d %k:00:00') AS DATETIME)

但是,在检测缺少样本的整个小时数方面并不是很好。它还对采样中的抖动有些敏感。也就是说,如果您的时间最多的样本有时是早半秒(10:59:30),有时又是半秒延迟(11:00:30),则您的每小时摘要计数将关闭。因此,该小时摘要(或日期摘要或分钟摘要等)不是安全的。

您需要一个自联接查询才能完全正确地进行操作。它有点像毛毛球,效率不高。

让我们首先创建一个带有编号样本的虚拟表(子查询)。(这在MySQL中是很痛苦的;其他一些昂贵的DBMS使其变得更容易。无论如何。)

  SELECT @sample:=@sample+1 AS entry_num, c.entry_time, c.value
    FROM (
        SELECT entry_time, value
      FROM table
         ORDER BY entry_time
    ) C,
    (SELECT @sample:=0) s

这个小的虚拟表提供了entry_num,entry_time,值。

下一步,我们将其加入自身。

SELECT one.entry_num, one.entry_time, one.value, 
       TIMEDIFF(two.value, one.value) interval
  FROM (
     /* virtual table */
  ) ONE
  JOIN (
     /* same virtual table */
  ) TWO ON (TWO.entry_num - 1 = ONE.entry_num)

这将表排成一行,每两个表之间偏移一个偏移量,该偏移量由JOIN的ON子句控制。

最后,我们从该表中选择一个interval大于阈值的值,并且在丢失样本之前就有样本的时间。

整体自连接查询是这个。我告诉过你那是一个毛线球。

SELECT one.entry_num, one.entry_time, one.value, 
       TIMEDIFF(two.value, one.value) interval
  FROM (
    SELECT @sample:=@sample+1 AS entry_num, c.entry_time, c.value
      FROM (
          SELECT entry_time, value
            FROM table
           ORDER BY entry_time
      ) C,
      (SELECT @sample:=0) s
  ) ONE
  JOIN (
    SELECT @sample2:=@sample2+1 AS entry_num, c.entry_time, c.value
      FROM (
          SELECT entry_time, value
            FROM table
           ORDER BY entry_time
      ) C,
      (SELECT @sample2:=0) s
  ) TWO ON (TWO.entry_num - 1 = ONE.entry_num)

如果必须在大型表上的生产中执行此操作,则可能需要对数据的子集执行此操作。例如,您可以每天为前两天的样本进行处理。这样会非常有效,并且还可以确保您不会在午夜忽略任何丢失的样本。为此,您的小行编号虚拟表将如下所示。

  SELECT @sample:=@sample+1 AS entry_num, c.entry_time, c.value
    FROM (
        SELECT entry_time, value
      FROM table
         ORDER BY entry_time
         WHERE entry_time >= CURRENT_DATE - INTERVAL 2 DAY
           AND entry_time < CURRENT_DATE /*yesterday but not today*/
    ) C,
    (SELECT @sample:=0) s


 类似资料:
  • 问题内容: 假设我们有两个连续的整数序列缺失,并且缺失的元素位于第一个元素与最后一个元素之间。我确实写了完成任务的代码。但是,我想尽可能地使用更少的循环来提高效率。任何帮助将不胜感激。当我们必须找到更多的缺失项(例如接近n / 4)而不是2时,情况又如何呢?我认为我的代码应该是高效的,因为我早先退出了循环? 问题答案: 假定L是没有重复的整数列表,则可以推断出,当且仅当且仅当且仅当且仅当且仅当且仅

  • 问题内容: 我有下表,其中包含每15分钟从几个不同的设备读取的值: 我想在表中找到每个月在给定月份中没有条目的所有设备的所有差距。对于上表,结果应该是这样的: 该表大约有35000台设备和1亿个条目。 这是我尝试过的;它很慢,但是返回我需要的。但是,除了速度之外,还有另一个问题:它只能找到在给定月份设备的最后一个条目之前丢失的时间间隔;之后的所有内容都将被忽略,因此有可能会错过额外的缺失值间隔。

  • 问题内容: 我正在尝试根据时间序列数据上的滑动窗口提取特征。在Scala中,似乎有一个基于此帖子和文档的功能 我的问题是PySpark是否有类似的功能?或者,如果还没有这样的功能,我们如何实现类似的滑动窗口转换? 问题答案: 据我所知,函数在Python中不可用,是私有类,不能在外部访问。 如果要在现有的RDD上使用,则可以这样创建可怜人: 或者,您可以尝试这样的操作(在的帮助下)

  • 假设我有一个股票市场交易事件流,如下所示: 使得technicalN(其中N是一些数字)代表给定公司的日终股票市场交易数据的第N个技术交易条目[开盘(浮动)、高位(浮动)、低位(浮动)、收盘(浮动)、成交量(int)]。(即ticker GOOG的技术1不同于ticker MSFT的技术1。)如: (请注意,这些交易价格/交易量完全是虚构的。 假设我想创建一个大小为2、时间间隔为1天的窗口,这样我

  • 问题内容: 有没有一种方法可以使用Oracle分析功能为数据集生成时间序列预测?我们如何在SQL / ORACLE中执行外推。 下面是我的需要 我有如下数据集,我想预测/推断明年 问题答案: 您可以使用REGR线性回归函数创建简单的预测。 下面是示例架构。或者,您可以使用此SQLFiddle。 该函数处理数字对,它不理解诸如“收入不能低于0”之类的业务规则。如果您希望将预测限制为始终保持在0或之上

  • 经过仔细的研究和思考,我决定发布这个问题,这是我今天早些时候提出的上一个问题的“续集”。 我做了一个算法,可以找到ArrayList的中值,基本上我所做的就是创建一个临时ArrayList,然后使用集合。在那个ArrayList上,我可以很容易地得到中值。问题是,对于较大的文件来说需要花费太长的时间,我正在尝试(运气不佳)找到一种算法的实现,以获得未排序数组(或ArrayList)的中值。 从我在