Pergunta

Problema:

Eu tenho um banco de dados de leituras de sensores com um timestamp para o tempo o sensor foi lido. Basicamente, parece que isso:

Sensor | Timestamp | Value

Agora eu quero fazer um gráfico de dados e eu quero fazer vários gráficos diferentes. Digamos que eu queira um para o último dia, um para a última semana e uma para o mês passado. A resolução de cada gráfico será muito diferente para o dia-a resolução gráfico seria de 1 minuto. Para o gráfico semana seria uma hora, e para o gráfico mês seria um dia, ou um quarto de um dia.

Então, eu gostaria de uma saída que é a média de cada resolução (por exemplo. Dia = Média sobre o minuto, Semana = Média sobre a hora e assim por diante)

Ex:

Sensor | Start | End | Average

Como posso fazer isso com facilidade e rapidez no MySQL? Eu suspeito que invoves criação de uma tabela temporária ou tipos e juntando os dados do sensor com que para obter os valores médios do sensor? Mas o meu conhecimento de mySQL é limitado na melhor das hipóteses.

Existe uma maneira muito inteligente de fazer isso?

Foi útil?

Solução

SELECT  DAY(Timestamp), HOUR(Timestamp), MINUTE(Timestamp), AVG(value)
FROM    mytable
GROUP BY
        DAY(Timestamp), HOUR(Timestamp), MINUTE(Timestamp) WITH ROLLUP

cláusula WITH ROLLUP aqui produz linhas extras com as médias para cada HOUR e DAY, como este:

SELECT  DAY(ts), HOUR(ts), MINUTE(ts), COUNT(*)
FROM    (
        SELECT  CAST('2009-06-02 20:00:00' AS DATETIME) AS ts
        UNION ALL
        SELECT  CAST('2009-06-02 20:30:00' AS DATETIME) AS ts
        UNION ALL
        SELECT  CAST('2009-06-02 21:30:00' AS DATETIME) AS ts
        UNION ALL
        SELECT  CAST('2009-06-03 21:30:00' AS DATETIME) AS ts
        ) q
GROUP BY
        DAY(ts), HOUR(ts), MINUTE(ts) WITH ROLLUP
2, 20, 0, 1
2, 20, 30, 1
2, 20, NULL, 2
2, 21, 30, 1
2, 21, NULL, 1
2, NULL, NULL, 3
3, 21, 30, 1
3, 21, NULL, 1
3, NULL, NULL, 1
NULL, NULL, NULL, 4

2, 20, NULL, 2 aqui significa que COUNT(*) é 2 para DAY = 2, HOUR = 20 e todos os minutos.

Outras dicas

Não é bem a tabela de resultados que você queria, mas aqui é um fermento para fazer uma resolução de 1 minuto:

SELECT sensor,minute(timestamp),avg(value) 
FROM table 
WHERE <time period specifier limits to a single hour>
GROUP BY sensor, minute(timestamp)

Eu tenho código usado muito semelhante a esta (não testado, mas ele está tomando a partir do código de trabalho)

definir as variáveis:

$seconds = 3600;
$start = mktime(...);  // say 2 hrs ago
$end   = .... // 1 hour after $start

, em seguida, executar a consulta

SELECT MAX(`when`) AS top_When, MIN(`when`) AS low_When,
   ROUND(AVG(sensor)) AS Avg_S,
   (MAX(`when`) - MIN(`when`)) AS dur, /* the duration in seconds of the actual period */
   ((floor(UNIX_TIMESTAMP(`when`) / $seconds)) * $seconds) as Epoch
   FROM `sensor_stats`
   WHERE `when` >= '$start' AND `when` <= '$end' and duration=30
   GROUP BY Epoch/*((floor(UNIX_TIMESTAMP(`when`) / $seconds)) * $seconds)*/

A vantagem disso é que você pode ter o que períodos de tempo que você quiser -. E nem mesmo obrigados a tê-los em 'números redondos', como um relógio horas completo (até mesmo um relógio minutos, 0-59)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top