Элегантный метод для рисования почасовой гистограммы из данных временного интервала? - PullRequest
3 голосов
/ 17 сентября 2008

У меня есть список записей расписания, которые показывают время начала и окончания. Это сидит в базе данных MySQL. Мне нужно создать гистограммы, основанные на этих данных, с указанием времени суток внизу и количества отработанных человеко-часов на каждый час дня.

Например, если Алиса работала с 15:30 до 19:30, а Боб работал с 12:15 до 17:00, график будет выглядеть так:

Example Chart

У меня сейчас есть решение WTFey, которое включает электронную таблицу, выходящую в столбец DY или что-то в этом роде. Требуемое разрешение - 15-минутные интервалы.

Я предполагаю, что это лучше всего сделать в базе данных, а затем экспортировать для создания диаграмм. Дайте мне знать, если я упустил какие-либо детали. Спасибо.

Ответы [ 4 ]

2 голосов
/ 17 сентября 2008

Создайте таблицу, в которой будет только время от полуночи до полуночи, содержащее каждую минуту дня. В мире хранилищ данных мы бы назвали это измерением времени. Вот пример:

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
0 голосов
/ 17 сентября 2008

Как насчет этого:

Используйте эту таблицу времен, но с двумя столбцами, содержащими 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

выглядит примерно так ...

0 голосов
/ 17 сентября 2008

Вот еще одно решение псевдокода под другим углом; немного интенсивнее, потому что он делает 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)
0 голосов
/ 17 сентября 2008

Я придумал решение с псевдокодом, надеюсь, оно поможет.

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 минут.

...