Méthode élégante pour dessiner un graphique à barres horaire à partir de données d'intervalle de temps?
Question
J'ai une liste d'entrées de la feuille de temps indiquant les heures de début et de fin. Ceci est assis dans une base de données MySQL. Je dois créer des diagrammes à barres basés sur ces données, avec les 24 heures de la journée en bas et le nombre d'heures-homme travaillées pour chaque heure de la journée.
Par exemple, si Alice travaillait de 15h30 à 19h30 et Bob de 12h15 à 17h00, le graphique ressemblerait à ceci:
J'ai actuellement une solution WTFey qui implique un tableur dans la colonne DY ou quelque chose comme ça. La résolution requise est de 15 minutes.
Je suppose que cette opération est préférable dans la base de données, puis exportée pour la création de graphique. Faites-moi savoir s'il me manque des détails. Merci.
La solution
Créez un tableau contenant uniquement l'heure de minuit à minuit et contenant chaque minute de la journée. Dans le monde des entrepôts de données, nous appellerions cela une dimension temporelle. Voici un exemple:
TIME_DIM
-id
-time_of_day
-interval_15
-interval_30
un exemple des données de la table serait
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
Ensuite, tout ce que vous avez à faire est de joindre votre table à la dimension time, puis de grouper par intervalle_15. Par exemple:
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
Autres conseils
Je suis arrivé avec une solution de pseudocode, espérons que cela aide.
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
Le tableau d’horaires contient maintenant les valeurs que vous désirez en 15 minutes, par exemple. une valeur de 4 = 1 heure, 5 = 1 heure 15 minutes, 14 = 3 heures 30 minutes.
Voici une autre solution de pseudocode sous un angle différent; un peu plus intensif car il fait 96 requêtes pour chaque période de 24 heures:
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)
Que diriez-vous de cela:
Utilisez-le & fois; fois " table, mais avec deux colonnes, contenant les intervalles de 15 minutes. Les from_times sont les 15 minutes, ils sont une seconde avant le prochain from_times. Par exemple, de 12h30 à 12h44:59.
Maintenant, obtenez votre table de travail personnelle, que j'ai appelée "activité". ici, avec les colonnes start_time et end_time.
J'ai ajouté des valeurs pour Alice et Bob conformément à la question initiale.
Voici la requête de 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)
qui me donne ceci:
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
Regarde à droite ...