1

私は 92.000 行を超える MySQL データベースを持っており、30 分ごとに気象情報が登録されています。日 | 日 | 月 | 月 | 年 | 年 | 時間 | 温度 |... (PHP で) 取得しようとしています ピーク温度: 各月の温度 =< 分(温度)+3 の最大時間 (連続レジスタ) を表示します。

助けていただければ幸いです。

4

1 に答える 1

0

これに対する私のアプローチ: 時系列の観測から始めて、それぞれにシリアル番号を付けます。

このシリアル番号付けは、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を見てください: http://sqlfiddle.com/#!2/d81e2/5/0

OK、それはかなり些細なことです。ここで、気温が 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です: http://sqlfiddle.com/#!2/d81e2/6/0

次のトリックは、このシーケンスの時間ギャップを見つけることです。これを行うには、この SO 投稿の手法を使用できます。MySQLで時系列データのギャップを見つける方法は?

次のステップでは、それ自体に結合します。

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)

このクエリは、シリーズ内の各アイテムとその次のアイテムの間の時間差を取得します。これは概念的には簡単なことですが、MySQL バージョンの SQL では注意が必要です。これが完全なクエリです。

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)

ここに sqlfiddle があります: http://sqlfiddle.com/#!2/d81e2/13/0 一部のギャップは 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 度を超える一連の時間ごとに 1 つの行が得られます。最初に最長時間。結果セットに表示される項目は、上昇する前に最後に 25 度を下回ったときの温度です。SQL フィドル。 http://sqlfiddle.com/#!2/d81e2/14/0

楽しいね?

于 2013-06-17T02:31:26.137 に答える