Min tilgang til dette:start med tidsrækken af observationer, og giv hver enkelt et serienummer.
Denne serienummerering er en smerte i nakken i MySQL, men lige meget. Givet en tabel med en ts-kolonne (et datetime-element) og en temp-kolonne, er her forespørgslen for at få dem med serienumre.
SELECT @sample:[email protected]+1 AS ser, ts, temp
FROM (
SELECT ts,temp
FROM t
ORDER BY ts
) C,
(SELECT @sample:=0) s
Tag et kig på denne sqlfiddle:http://sqlfiddle.com/#!2/ d81e2/5/0
OK, det er ret trivielt. Lad os nu sige, at vi leder efter perioder, hvor temperaturen er 25 grader eller derover. For at gøre dette skal vi skære tidsserien op, så den udelades disse observationer. Det går sådan her:
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
Her er sqlfiddle:http://sqlfiddle.com/#!2/d81e2/6 /0
Nu er det næste trick at finde tidshullerne i denne sekvens. Det kan vi bruge teknikken fra dette SO-indlæg til. Metode at finde huller i tidsseriedata i MySQL?
Næste trin forbinder vi det med sig selv.
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)
Denne forespørgsel henter tidsforskellen mellem hvert element i serien og det efter det. Det er en ligetil ting at gøre konceptuelt, men vanskelig i MySQL-versionen af SQL. Her er hele forespørgslen.
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)
Her er sqlfiddle:http://sqlfiddle.com/#!2/d81e2/13 /0 Bemærk, at nogle af hullerne er på 30 minutter. Det er normalt for på hinanden følgende aflæsninger. Nogle er 60 minutter. Det er også normalt, fordi den tidsserie, jeg bruger, mangler nogle poster. Indtastningerne i dette resultatsæt viser tiderne og temperaturerne umiddelbart før hullerne.
Så det eneste, der er tilbage, er at slippe af med uønsket huller (30 og 60 minutter) og derefter bestille de resterende huller i faldende rækkefølge.
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
Dette giver en række for hver tidssekvens, hvor temperaturen er over 25 grader; den længste tid først. Punktet vist i resultatsættet er den sidste tidstemperatur under 25, før den steg. SQL violin. http://sqlfiddle.com/#!2/d81e2/14/0
Sjovt, ikke?