Pendekatan saya untuk ini:mulailah dengan rangkaian pengamatan waktu, dan berikan masing-masing nomor seri.
Penomoran seri ini menyebalkan di MySQL, tapi tidak masalah. Diberikan tabel dengan kolom ts (item datetime) dan kolom temp, inilah kueri untuk mendapatkannya dengan nomor seri.
SELECT @sample:[email protected]+1 AS ser, ts, temp
FROM (
SELECT ts,temp
FROM t
ORDER BY ts
) C,
(SELECT @sample:=0) s
Lihatlah sqlfiddle ini:http://sqlfiddle.com/#!2/ d81e2/5/0
Oke, itu cukup sepele. Sekarang, katakanlah kita sedang mencari periode waktu di mana suhunya 25 derajat atau lebih. Untuk melakukan ini, kita perlu memotong deret waktu sehingga dihilangkan pengamatan tersebut. Itu seperti ini:
SELECT @sample:[email protected]+1 AS ser, ts, temp
FROM (
SELECT ts,temp
FROM t
WHERE NOT temp >= 25
ORDER BY ts
) C,
(SELECT @sample:=0) s
Berikut sqlfiddlenya:http://sqlfiddle.com/#!2/d81e2/6 /0
Sekarang trik selanjutnya adalah menemukan celah waktu dalam urutan ini. Kita dapat menggunakan teknik dari posting SO ini untuk melakukan itu. Metode menemukan kesenjangan dalam data deret waktu di MySQL?
Langkah selanjutnya, kita gabungkan dengan dirinya sendiri.
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)
Kueri ini mendapatkan jeda waktu antara setiap item dalam rangkaian dan item setelahnya. Ini adalah hal yang mudah untuk dilakukan secara konseptual, tetapi rumit dalam versi MySQL dari SQL. Berikut pertanyaan lengkapnya.
SELECT two.ser, two.ts, two.temp,
TIMESTAMPDIFF(MINUTE, two.ts, one.ts) gap
FROM (
SELECT @sample:[email protected]+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:[email protected]+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)
Berikut sqlfiddlenya:http://sqlfiddle.com/#!2/d81e2/13 /0 Perhatikan bahwa beberapa jeda berdurasi 30 menit. Itu normal untuk pembacaan berurutan. Ada yang 60 menit. Itu juga normal, karena deret waktu yang saya gunakan memiliki beberapa entri yang hilang. Entri dalam kumpulan hasil ini menunjukkan waktu dan suhu tepat sebelum jeda.
Jadi, yang tersisa hanyalah membuang celah sampah (30 dan 60 menit) dan kemudian mengurutkan celah yang tersisa dalam urutan menurun.
SELECT two.ts, two.temp,
TIMESTAMPDIFF(MINUTE, two.ts, one.ts) gap
FROM (
SELECT @sample:[email protected]+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:[email protected]+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
Ini memberikan satu baris untuk setiap urutan waktu di mana suhu di atas 25 derajat; paling lama dulu. Item yang ditampilkan dalam set hasil adalah suhu terakhir kali di bawah 25 sebelum naik. Biola SQL. http://sqlfiddle.com/#!2/d81e2/14/0
Menyenangkan, ya?