私は 92.000 行を超える MySQL データベースを持っており、30 分ごとに気象情報が登録されています。日 | 日 | 月 | 月 | 年 | 年 | 時間 | 温度 |... (PHP で) 取得しようとしています ピーク温度: 各月の温度 =< 分(温度)+3 の最大時間 (連続レジスタ) を表示します。
助けていただければ幸いです。
私は 92.000 行を超える MySQL データベースを持っており、30 分ごとに気象情報が登録されています。日 | 日 | 月 | 月 | 年 | 年 | 時間 | 温度 |... (PHP で) 取得しようとしています ピーク温度: 各月の温度 =< 分(温度)+3 の最大時間 (連続レジスタ) を表示します。
助けていただければ幸いです。
これに対する私のアプローチ: 時系列の観測から始めて、それぞれにシリアル番号を付けます。
このシリアル番号付けは、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
楽しいね?