Элегантный метод построения часовой гистограммы на основе данных временных интервалов?
Вопрос
У меня есть список записей расписания, в которых указано время начала и окончания.Это находится в базе данных MySQL.Мне нужно создать гистограммы на основе этих данных с указанием 24 часов дня внизу и количеством человеко-часов, отработанных за каждый час дня.
Например, если Алиса работала с 15:30 до 19:30, а Боб работал с 12:15 до 17:00, диаграмма выглядела бы так:
У меня сейчас есть WTFey-решение, которое включает в себя электронную таблицу, выводящуюся в столбец DY или что-то в этом роде.Необходимое разрешение — 15-минутные интервалы.
Я предполагаю, что это лучше всего сделать в базе данных, а затем экспортировать для создания диаграмм.Дайте мне знать, если я упускаю какие-либо детали.Спасибо.
Решение
Создайте таблицу, содержащую только время с полуночи до полуночи, содержащую каждую минуту дня.В мире хранилищ данных мы бы назвали это измерением времени.Вот пример:
TIME_DIM
-id
-time_of_day
-interval_15
-interval_30
примером данных в таблице может быть
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
Затем все, что вам нужно сделать, это присоединить таблицу к измерению времени, а затем сгруппировать ее по интервалу_15.Например:
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
Другие советы
Я придумал решение для псевдокода, надеюсь, оно поможет.
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
Теперь массив расписаний содержит нужные значения с точностью до 15 минут, т.е.значение 4 = 1 час, 5 = 1 час 15 минут, 14 = 3 часа 30 минут.
Вот еще одно решение псевдокода под другим углом;немного более интенсивный, поскольку он выполняет 96 запросов за каждые 24 часа:
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)
Как насчет этого:
Используйте эту таблицу «время», но с двумя столбцами, содержащими 15-минутные интервалы.from_times — это 15-минутное время, to_times — за секунду до следующего from_times.Например, с 12:30:00 до 12:44:59.
Теперь возьмите рабочую таблицу вашего человека, которую я назвал здесь «активность», со столбцами start_time и end_time.
Я добавил значения для Алисы и Боба согласно исходному вопросу.
Вот запрос из 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)
что дает мне это:
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
Выглядит примерно правильно...