Reputation: 117
I have a list of timesheet entries that show a start and stop time. This is sitting in a MySQL database. I need to create bar charts based on this data with the 24 hours of the day along the bottom and the amount of man-hours worked for each hour of the day.
For example, if Alice worked a job from 15:30 to 19:30 and Bob worked from 12:15 to 17:00, the chart would look like this:
I have a WTFey solution right now that involves a spreadsheet going out to column DY or something like that. The needed resolution is 15-minute intervals.
I'm assuming this is something best done in the database then exported for chart creation. Let me know if I'm missing any details. Thanks.
Upvotes: 3
Views: 4277
Reputation: 52326
How about this:
Use that "times" table, but with two columns, containing the 15-minute intervals. The from_times are the 15-minutely times, the to_times are a second before the next from_times. For example 12:30:00 to 12:44:59.
Now get your person work table, which I've called "activity" here, with start_time and end_time columns.
I added values for Alice and Bob as per the original question.
Here's the query from 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)
which gives me this:
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
Looks about right...
Upvotes: 0
Reputation: 43057
Here's another pseudocode solution from a different angle; a bit more intensive because it does 96 queries for every 24hr period:
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)
Upvotes: 0
Reputation: 2992
Create a table with just time in it from midnight to midnight containing each minute of the day. In the data warehouse world we would call this a time dimension. Here's an example:
TIME_DIM
-id
-time_of_day
-interval_15
-interval_30
an example of the data in the table would be
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
Then all you have to do is join your table to the time dimension and then group by interval_15. For example:
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
Upvotes: 2
Reputation:
I came up with a pseudocode solution, hope it helps.
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
Now the timetable array holds the values you desire in 15 minute granularity, ie. a value of 4 = 1 hour, 5 = 1 hour 15 minutes, 14 = 3 hours 30 minutes.
Upvotes: 0