Minha abordagem para isso:comece com a série temporal de observações e dê a cada uma um número de série.
Esta numeração de série é uma dor de cabeça no MySQL, mas não importa. Dada uma tabela com uma coluna ts (um item de data e hora) e uma coluna temporária, aqui está a consulta para obtê-los com números de série.
SELECT @sample:[email protected]+1 AS ser, ts, temp
FROM (
SELECT ts,temp
FROM t
ORDER BY ts
) C,
(SELECT @sample:=0) s
Dê uma olhada neste sqlfiddle:http://sqlfiddle.com/#!2/ d81e2/5/0
OK, isso é bem trivial. Agora, digamos que estamos procurando períodos de tempo em que a temperatura é de 25 graus ou mais. Para fazer isso, precisamos cortar a série temporal para que ela omita essas observações. Isso fica assim:
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
Aqui está o sqlfiddle:http://sqlfiddle.com/#!2/d81e2/6 /0
Agora, o próximo truque é encontrar os intervalos de tempo nesta sequência. Podemos usar a técnica deste post SO para fazer isso. Método de encontrar lacunas nos dados de séries temporais no MySQL?
Próximo passo, nós o juntamos a si mesmo.
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)
Essa consulta obtém o intervalo de tempo entre cada item da série e o seguinte. É uma coisa simples de fazer conceitualmente, mas complicada na versão MySQL do SQL. Aqui está a consulta completa.
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)
Aqui está o sqlfiddle:http://sqlfiddle.com/#!2/d81e2/13 /0 Observe que alguns dos intervalos têm 30 minutos de duração. Isso é normal para leituras consecutivas. Alguns são 60 minutos. Isso também é normal, porque a série temporal que estou usando tem algumas entradas ausentes. As entradas neste conjunto de resultados mostram os tempos e temperaturas imediatamente antes dos intervalos.
Então, tudo o que resta é se livrar das lacunas de lixo (30 e 60 minutos) e depois ordenar as lacunas restantes em ordem decrescente.
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
Isso dá uma linha para cada sequência de tempo em que a temperatura está acima de 25 graus; o maior tempo primeiro. O item mostrado no conjunto de resultados é a última temperatura abaixo de 25 antes de subir. violino SQL. http://sqlfiddle.com/#!2/d81e2/14/0
Divertido, hein?