2013-09-22 21 views
7

Abbiamo un database MySQL in cui sono stati aggiunti i valori delle serie temporali.Dati delle serie temporali in MySQL: campionamento

------------------------------------- 
|Col A | Col B | Timestamp   | 
------------------------------------- 
|1.23 | 4.48 |2013-09-03 10:45:27 | 
------------------------------------- 
|1.23 | 4.48 |2013-09-03 10:46:27 | 
------------------------------------- 
|1.23 | 4.48 |2013-09-03 10:47:27 | 
------------------------------------- 

I dati sono distanziati in modo non uniforme tempo w.r.t, alcuni punti sono separati da un minuto & alcuni di pochi secondi.

Esiste un modo efficace per interrogare questo database per estrarre i dati per ogni n minuto/secondo/ora? Idealmente vorrei il valore interpolato (lineare) al minuto n, ma il punto più vicino al punto n o all'ultimo punto prima o al punto n sarebbe anche quello.

Il caso d'uso è che voglio tracciare questo in un grafico, ma non voglio troppi punti del necessario. Quindi, per il tracciamento di un anno, preferirei interrogare solo un paio di punti al giorno. Mentre pianifico per un giorno, vorrei tracciare un punto ogni minuto o così.

Posso fare tutto questo in PHP, ma c'è un modo per farlo direttamente nel database? In caso contrario, sto contemplando l'utilizzo di un database di serie temporali, ma i vincoli di budget mi limitano solo a quelli gratuiti. Esiste un database di serie temporali gratuito che fornisce il campionamento out of the box e preferibilmente l'interpolazione?

+0

possibile duplicato di [ Campionamento di timeseries SQL] (http://stackoverflow.com/questions/7335627/sampling-sql-timeseries) – Domi

risposta

0

Ho avuto una pugnalata a questo, sono davvero interessato a vedere come gli altri potrebbero risolverlo.

Avevo già un problema simile a questo e l'ho risolto creando una tabella di indici temporali e poi unendomi alla tabella di dati basata sulla riscrittura del tempo per adattarsi a un intervallo di tempo. Il problema è che hai bisogno di una nuova tabella degli indici temporali e di una query o di una visualizzazione separata per ogni intervallo di tempo.

Il vantaggio di unire i dati in questo modo era che mi interessavano anche gli intervalli di tempo in cui non c'era alcuna lettura o risultato, quindi avevo bisogno di vedere i valori nulli o senza letture per determinati intervalli di tempo. C'è solo un piccolo lavoro in più richiesto con i dati finali per quello (cioè: togliere i Segnaposti).

La prima cosa che ho fatto, è stato creare una tabella indice temporale, sembra qualcosa di simile ....

mysql> select * from ctb_time_idx WHERE YEAR(ctb_datetime) = 2013 LIMIT 10 ; 
+---------------------+ 
| ctb_datetime  | 
+---------------------+ 
| 2013-01-01 00:00:00 | 
| 2013-01-01 00:15:00 | 
| 2013-01-01 00:30:00 | 
| 2013-01-01 00:45:00 | 
| 2013-01-01 01:00:00 | 
| 2013-01-01 01:15:00 | 
| 2013-01-01 01:30:00 | 
| 2013-01-01 01:45:00 | 
| 2013-01-01 02:00:00 | 
| 2013-01-01 02:15:00 | 
+---------------------+ 
10 rows in set (0.07 sec) 

Ho poi unione miei dati in

(select 
    ctb_datetime AS time1 , 
    'Placeholder' AS TimeInterval , 
    NULL AS `Col A` , 
    NULL AS `Col B` 
from my_time_idx 
    where YEAR (ctb_time_idx.ctb_datetime ) = 2013) 
UNION 
(select DATE_FORMAT(time1 , '%Y-%m-%d %H:00') AS time1 , 
    '00min' AS TimeInterval , `Col A` , `Col B` from my_data_table 
    where MINUTE(time1) BETWEEN 00 AND 14 ) 
UNION 
(select DATE_FORMAT(time1 , '%Y-%m-%d %H:15') AS time1 , 
    '15min' AS TimeInterval, `Col A` , `Col B` from my_data_table 
    where MINUTE(time1) BETWEEN 15 AND 29 ) 
UNION 
(select DATE_FORMAT(time1 , '%Y-%m-%d %H:30') AS time1 , 
    '30min' AS TimeInterval, `Col A` , `Col B` from my_data_table 
    where MINUTE(time1) BETWEEN 30 AND 44 ) 
UNION 
(select DATE_FORMAT(time1 , '%Y-%m-%d %H:45') AS time1 , 
    '45min' AS TimeInterval, `Col A` , `Col B` from my_data_table 
    where MINUTE(time1) BETWEEN 45 AND 59 )  
order by time1 

Ho provato questo su i miei vecchi tavoli e sembra funzionare bene, ho dovuto ri-modificare il mio codice per soddisfare il tuo esempio, quindi spero di non aver rovinato tutto quando lo faccio.

+0

Immagino che questo sarà estremamente lento, a meno che non si aggiunga un indice fulltext sulla colonna timestamp – Domi

-1
select unix_timestamp(now()); 
select from_unixtime(unix_timestamp(now())); 
select from_unixtime(unix_timestamp(now())-unix_timestamp(now())%300); 
select from_unixtime(unix_timestamp(now())-unix_timestamp(now())%900); 
select from_unixtime(unix_timestamp(now())-unix_timestamp(now())%1800); 

+-----------------------+ 
| unix_timestamp(now()) | 
+-----------------------+ 
|   1383077951 | 
+-----------------------+ 
1 row in set (0.00 sec) 

+--------------------------------------+ 
| from_unixtime(unix_timestamp(now())) | 
+--------------------------------------+ 
| 2013-10-29 20:19:11     | 
+--------------------------------------+ 
1 row in set (0.00 sec) 

+----------------------------------------------------------------+ 
| from_unixtime(unix_timestamp(now())-unix_timestamp(now())%300) | 
+----------------------------------------------------------------+ 
| 2013-10-29 20:15:00           | 
+----------------------------------------------------------------+ 
1 row in set (0.00 sec) 

+----------------------------------------------------------------+ 
| from_unixtime(unix_timestamp(now())-unix_timestamp(now())%900) | 
+----------------------------------------------------------------+ 
| 2013-10-29 20:15:00           | 
+----------------------------------------------------------------+ 
1 row in set (0.00 sec) 

+-----------------------------------------------------------------+ 
| from_unixtime(unix_timestamp(now())-unix_timestamp(now())%1800) | 
+-----------------------------------------------------------------+ 
| 2013-10-29 20:00:00            | 
+-----------------------------------------------------------------+ 
1 row in set (0.00 sec) 
+1

Benvenuti in SO. Oltre al codice si prega di aggiungere una spiegazione nella risposta. Spiega OP in che modo ciò è utile, cosa gli manca, o qualsiasi altra cosa che aiuti le persone a capire perché questa è una risposta utile/utile. Vedi [Come scrivere una buona risposta?] (Http://stackoverflow.com/help/how-to-answer) – dic19

0

non ho usato io stesso, ma di recente sono imbattuto InfluxDB che suona come esso potrebbe soddisfare i criteri di - una banca dati di serie temporali open source con costruito in aggregation queries - esempio

SELECT MEAN(column_name) FROM series_name group by time(10m) 
Problemi correlati