Php 检测时间序列中符合特定条件的连续项

Php 检测时间序列中符合特定条件的连续项,php,mysql,time-series,Php,Mysql,Time Series,我有一个MySQL数据库,每半小时就有超过92000行气象记录。 日|月|年|时间|温度|。。。 我试图获得(在PHP中)峰值温度:显示每个月温度=

我有一个MySQL数据库,每半小时就有超过92000行气象记录。 日|月|年|时间|温度|。。。 我试图获得(在PHP中)峰值温度:显示每个月温度=
我将感谢任何帮助

我的方法是:从观察的时间序列开始,给每个时间序列一个序列号

在MySQL中,这个序列号是一个让人头疼的问题,但没关系。给定一个带有ts列(一个datetime项)和temp列的表,下面是使用序列号获取它们的查询

SELECT @sample:=@sample+1 AS ser, ts, temp
  FROM (
     SELECT ts,temp
       FROM t
      ORDER BY ts
    ) C,
  (SELECT @sample:=0) s 
看看这个sqlfiddle:

好吧,那是很琐碎的。现在,假设我们正在寻找温度在25度或以上的时间段。要做到这一点,我们需要把时间序列切碎,这样它就忽略了这些观察结果。事情是这样的:

SELECT @sample:=@sample+1 AS ser, ts, temp
  FROM (
     SELECT ts,temp
       FROM t
      WHERE NOT temp >= 25
      ORDER BY ts
    ) C,
  (SELECT @sample:=0) s
下面是sqlfiddle:

现在,下一个技巧是找到这个序列中的时间间隔。我们可以使用这篇文章中的技巧来做到这一点

下一步,我们将它自身连接起来

SELECT two.ser, two.ts, two.temp, 
       TIMESTAMPDIFF(MINUTE, two.ts, one.ts) gap
  FROM (
     /* virtual table */
  ) ONE
  JOIN (
     /* same virtual table */
  ) TWO ON (TWO.ser+ 1 = ONE.ser)
此查询获取序列中的每个项与其后的项之间的时间间隔。从概念上讲,这是一件简单的事情,但在SQL的MySQL版本中却很棘手。这是完整的查询

SELECT two.ser, two.ts, two.temp, 
       TIMESTAMPDIFF(MINUTE, two.ts, one.ts) gap
      FROM (
 SELECT @sample:=@sample+1 AS ser, ts, temp
  FROM (
     SELECT ts,temp
       FROM t
      WHERE NOT temp >= 25
      ORDER BY ts
    ) C,
  (SELECT @sample:=0) s
      ) ONE
      JOIN (
SELECT @sample2:=@sample2+1 AS ser, ts, temp
  FROM (
     SELECT ts,temp
       FROM t
      WHERE NOT temp >= 25
      ORDER BY ts
    ) C,
  (SELECT @sample2:=0) s
      ) TWO ON (TWO.ser+ 1 = ONE.ser)
这里是SQLFIDLE:请注意,有些间隙的持续时间为30分钟。这是正常的连续读数。有些是60分钟。这也是正常的,因为我使用的时间序列缺少一些条目。此结果集中的条目显示间隙前的时间和温度

所以,剩下的就是去掉垃圾间隙(30分钟和60分钟),然后按降序排列剩余间隙

SELECT two.ts, two.temp, 
       TIMESTAMPDIFF(MINUTE, two.ts, one.ts) gap
      FROM (
 SELECT @sample:=@sample+1 AS ser, ts, temp
  FROM (
     SELECT ts,temp
       FROM t
      WHERE NOT temp >= 25
      ORDER BY ts
    ) C,
  (SELECT @sample:=0) s
      ) ONE
      JOIN (
SELECT @sample2:=@sample2+1 AS ser, ts, temp
  FROM (
     SELECT ts,temp
       FROM t
      WHERE NOT temp >= 25
      ORDER BY ts
    ) C,
  (SELECT @sample2:=0) s
      ) TWO ON (TWO.ser+ 1 = ONE.ser)
 WHERE TIMESTAMPDIFF(MINUTE, two.ts, one.ts)> 60
 ORDER BY TIMESTAMPDIFF(MINUTE, two.ts, one.ts) DESC
这为温度高于25度的每个时间序列提供了一行;最长的时间是第一次。结果集中显示的项目是温度上升前最后一次低于25度。SQL小提琴


有趣,是吗?

您可以在sqlfiddle.com上放置一些示例数据,并展示一些您尝试过的内容。我不知道的是如何计算连续寄存器。。。我的意思是,这个条件连续满足了多少次。这是一个可能的起点。非常感谢您的回答,我会尽快尝试。以正确的方式消化这段代码对我来说很复杂,但我可以根据我的数据进行调整,经过16分钟的处理,我可以获得结果。是否可以按月份对它们进行分组?您可以在两个子查询中选择时间子集。但要注意,当你逐月进行测量时,你的测量可能会有一点失真。从6月最后几天开始,一直持续到7月的热浪不会出现。在我的笔记本电脑上,用大约73K个观测数据集进行了两分钟的查询。