Metodo elegante per disegnare un grafico a barre orario dai dati di intervallo di tempo?
Domanda
Ho un elenco di voci della scheda attività che mostrano un'ora di inizio e di fine.Questo è seduto in un database MySQL.Devo creare grafici a barre basati su questi dati con le 24 ore del giorno in basso e la quantità di ore di lavoro lavorate per ciascuna ora del giorno.
Ad esempio, se Alice svolgesse un lavoro dalle 15:30 alle 19:30 e Bob lavorasse dalle 12:15 alle 17:00, il grafico sarebbe simile al seguente:
Ho una soluzione WTFey in questo momento che prevede un foglio di calcolo che esce nella colonna DY o qualcosa del genere.La risoluzione necessaria è intervalli di 15 minuti.
Presumo che sia meglio farlo nel database e poi esportarlo per la creazione del grafico.Fammi sapere se mi manca qualche dettaglio.Grazie.
Soluzione
Crea una tabella con solo l'ora da mezzanotte a mezzanotte contenente ogni minuto della giornata.Nel mondo del data warehouse la chiameremmo dimensione temporale.Ecco un esempio:
TIME_DIM
-id
-time_of_day
-interval_15
-interval_30
un esempio dei dati nella tabella sarebbe
id time_of_day interval_15 interval_30
1 00:00 00:00 00:00
...
30 00:23 00:15 00:00
...
100 05:44 05:30 05:30
Quindi tutto ciò che devi fare è unire la tua tabella alla dimensione temporale e quindi raggrupparla per intervallo_15.Per esempio:
SELECT b.interval_15, count(*)
FROM my_data_table a
INNER JOIN time_dim b ON a.time_field = b.time
WHERE a.date_field = now()
GROUP BY b.interval_15
Altri suggerimenti
Ho trovato una soluzione in pseudocodice, spero che sia d'aiuto.
create an array named timetable with 24 entries
initialise timetable to zero
for each user in SQLtable
firsthour = user.firsthour
lasthour = user.lasthour
firstminutes = 4 - (rounded down integer(user.firstminutes/15))
lastminutes = rounded down integer(user.lastminutes/15)
timetable(firsthour) = timetable(firsthour) + firstminutes
timetable(lasthour) = timetable(lasthour) + lastminutes
for index=firsthour+1 to lasthour-1
timetable(index) = timetable(index) + 4
next index
next user
Ora l'array dell'orario contiene i valori desiderati con una granularità di 15 minuti, ad es.un valore di 4 = 1 ora, 5 = 1 ora e 15 minuti, 14 = 3 ore e 30 minuti.
Ecco un'altra soluzione di pseudocodice da una diversa angolazione;un po' più intenso perché esegue 96 query per ogni periodo di 24 ore:
results = []
for time in range(0, 24, .25):
amount = mysql("select count(*) from User_Activity_Table where time >= start_time and time <= end_time")
results.append(amount)
Cosa ne pensi di questo:
Usa la tabella "tempi", ma con due colonne, contenenti gli intervalli di 15 minuti.I from_times sono tempi di 15 minuti, i to_times sono un secondo prima del successivo from_times.Ad esempio dalle 12:30:00 alle 12:44:59.
Ora prendi la tabella di lavoro della tua persona, che qui ho chiamato "attività", con le colonne start_time e end_time.
Ho aggiunto valori per Alice e Bob come da domanda originale.
Ecco la query da MySQL:
SELECT HOUR(times.from_time) AS 'TIME', count(*) / 4 AS 'HOURS'
FROM times
JOIN activity
ON times.from_time >= activity.start_time AND
times.to_time <= activity.end_time
GROUP BY HOUR(times.from_time)
ORDER BY HOUR(times.from_time)
che mi dà questo:
TIME HOURS
12 0.7500
13 1.0000
14 1.0000
15 1.5000
16 2.0000
17 1.0000
18 1.0000
19 0.7500
Sembra giusto...