1日あたりおよび1時間あたりに実行されたタスクの量のレポートを生成する必要があります。このように、レポートはグリッドのように見えます。
横軸は曜日(1〜31)、縦軸は時間(8:00〜18:00)をお願いします。
PostgreSQLでSQLを使用してデータベースからこの種のデータを選択するにはどうすればよいですか?
1日あたりおよび1時間あたりに実行されたタスクの量のレポートを生成する必要があります。このように、レポートはグリッドのように見えます。
横軸は曜日(1〜31)、縦軸は時間(8:00〜18:00)をお願いします。
PostgreSQLでSQLを使用してデータベースからこの種のデータを選択するにはどうすればよいですか?
探しているクエリはSQL集計クエリです。少し複雑に見えるかもしれませんが、構造はかなり簡単です。
select extract(hour from date_time_of_task) as thehour,
sum(case when extract(day from date_time_of_task) = 1 then 1 else 0 end) as day_01,
sum(case when extract(day from date_time_of_task) = 2 then 1 else 0 end) as day_02,
sum(case when extract(day from date_time_of_task) = 3 then 1 else 0 end) as day_03,
sum(case when extract(day from date_time_of_task) = 4 then 1 else 0 end) as day_04,
... up to day 31
group by extract(hour from date_time_of_task)
order by 1
これは、単に1日の時間でグループ化したものです。次に、その月の各日にデータを手動でピボットします。「合計」は、2つの条件を満たす行の数(行の時間と列の日)を同時にカウントします。
洗練されたソリューションの重要な要素は、、、generate_series()
CTE 、および、そして最後に、追加のモジュールtablefuncからの関数(1つのパラメーターを持つ)です。これをインストールするには、データベースごとに1回実行します。date_part()
GROUP BY
count(*)
LEFT JOIN
crosstab()
CREATE EXTENSION tablefunc;
クエリ:
SELECT *
FROM crosstab($x$
WITH x AS (
SELECT date_part('day', date_time_of_task)::int AS d
,date_part('hour', date_time_of_task)::int AS h
,count(*)::int AS ct
FROM tasks
GROUP BY 1,2
)
SELECT d, h, ct
FROM (SELECT generate_series(1,31) AS d, generate_series(0,23) AS h) t
LEFT JOIN x USING (d,h)
ORDER BY 1,2
$x$)
AS orders(
day int
,h8 int, h9 int, h10 int, h11 int, h12 int, h13 int, h14 int, h15 int
,h16 int, h17 int, h18 int);
あなたが説明するように、各フィールドのタスクの数で日と時間のマトリックスを生成します。
ところで:私はこの補助を使用しました。ターゲット定義リストを生成する関数:
SELECT 'day int, ' || string_agg (x, ', ')
FROM (SELECT ('h' || generate_series(8,18) || ' int') AS x) a