時間間隔データから時間ごとの棒グラフを描画するエレガントな方法?
質問
開始時刻と終了時刻を示すタイムシート エントリのリストがあります。これは MySQL データベース内にあります。このデータに基づいて、1 日の 24 時間を下に示し、1 日の各時間の作業工数を示す棒グラフを作成する必要があります。
たとえば、アリスが 15:30 から 19:30 まで仕事をし、ボブが 12:15 から 17:00 まで働いた場合、グラフは次のようになります。
私は現在、列 DY またはそのようなものに出力されるスプレッドシートを含む WTFey ソリューションを持っています。必要な解像度は 15 分間隔です。
これはデータベースで実行してからグラフ作成のためにエクスポートするのが最適だと思います。詳細が不足している場合はお知らせください。ありがとう。
解決
午前 0 時から午前 0 時までの 1 日の各分を含む時間だけを含むテーブルを作成します。データ ウェアハウスの世界では、これを時間ディメンションと呼びます。以下に例を示します。
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
次に、テーブルを時間ディメンションに結合し、interval_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
これで、timetable 配列には、必要な値が 15 分単位で保持されます。値 4 = 1 時間、5 = 1 時間 15 分、14 = 3 時間 30 分。
ここでは、別の角度から見た別の疑似コード ソリューションを示します。24 時間ごとに 96 個のクエリを実行するため、もう少し集中的になります。
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 分間隔を含む 2 つの列があります。from_times は 15 分ごとの時刻、to_times は次の from_times の 1 秒前です。たとえば、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
ほぼ正しいように見えます...