時間間隔データから時間ごとの棒グラフを描画するエレガントな方法?

StackOverflow https://stackoverflow.com/questions/79789

  •  09-06-2019
  •  | 
  •  

質問

開始時刻と終了時刻を示すタイムシート エントリのリストがあります。これは MySQL データベース内にあります。このデータに基づいて、1 日の 24 時間を下に示し、1 日の各時間の作業工数を示す棒グラフを作成する必要があります。

たとえば、アリスが 15:30 から 19:30 まで仕事をし、ボブが 12:15 から 17:00 まで働いた場合、グラフは次のようになります。

Example Chart

私は現在、列 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

ほぼ正しいように見えます...

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top