2017-11-17 14 views
0

「タイムエントリ」のテーブルから、各ユーザの週別合計のレポートを作成しようとしています。テーブルのPostgreSQL Crosstab generate_seriesカラムの週数

サンプル:

+-----+---------+-------------------------+--------------+ 
| id | user_id | start_time    | hours_worked | 
+-----+---------+-------------------------+--------------+ 
| 997 | 6  | 2018-01-01 03:05:00 UTC | 1.0   | 
| 996 | 6  | 2017-12-01 05:05:00 UTC | 1.0   | 
| 998 | 6  | 2017-12-01 05:05:00 UTC | 1.5   | 
| 999 | 20  | 2017-11-15 19:00:00 UTC | 1.0   | 
| 995 | 6  | 2017-11-11 20:47:42 UTC | 0.04   | 
+-----+---------+-------------------------+--------------+ 

今、私は次のことを実行して、基本的に私はこれが

+-------+---------+------------+ 
| total | user_id | week  | 
+-------+---------+------------+ 
| 14.08 | 5  | 2017-10-30 | 
| 21.92 | 6  | 2017-10-30 | 
| 10.92 | 7  | 2017-10-30 | 
| 14.26 | 8  | 2017-10-30 | 
| 14.78 | 10  | 2017-10-30 | 
| 14.08 | 13  | 2017-10-30 | 
| 15.83 | 15  | 2017-10-30 | 
| 8.75 | 5  | 2017-11-06 | 
| 10.53 | 6  | 2017-11-06 | 
| 13.73 | 7  | 2017-11-06 | 
| 14.26 | 8  | 2017-11-06 | 
| 19.45 | 10  | 2017-11-06 | 
| 15.95 | 13  | 2017-11-06 | 
| 14.16 | 15  | 2017-11-06 | 
| 1.00 | 20  | 2017-11-13 | 
| 0  |   | 2017-11-20 | 
| 2.50 | 6  | 2017-11-27 | 
| 0  |   | 2017-12-04 | 
| 0  |   | 2017-12-11 | 
| 0  |   | 2017-12-18 | 
| 0  |   | 2017-12-25 | 
+-------+---------+------------+ 

を返します

SELECT COALESCE(SUM(time_entries.hours_worked),0) AS total, 
    time_entries.user_id, 
    week::date 

--Using generate_series here to account for weeks with no time entries when 
--doing the join 

FROM generate_series((DATE_TRUNC('week', '2017-11-01 00:00:00'::date)), 
         (DATE_TRUNC('week', '2017-12-31 23:59:59.999999'::date)), 
         interval '7 day') as week LEFT JOIN time_entries 
ON DATE_TRUNC('week', time_entries.start_time) = week 

GROUP BY week, time_entries.user_id 
ORDER BY week 

が必要なものを得ることができますしかし、これはあります特に1週間のデータがない場合は解析が困難です。私が望むのは、週が列で、行がユーザーであるピボットまたはクロス集計表です。また、各自からのヌルを含めることもできます(たとえば、ユーザーがその週または週にエントリを持たず、ユーザーからのエントリがない場合など)。この

+---------+---------------+--------------+--------------+ 
| user_id | 2017-10-30 | 2017-11-06 | 2017-11-13 | 
+---------+---------------+--------------+--------------+ 
| 6  | 4.0   | 1.0   | 0   | 
| 7  | 4.0   | 1.0   | 0   | 
| 8  | 4.0   | 0   | 0   | 
| 9  | 0    | 1.0   | 0   | 
| 10  | 4.0   | 0.04   | 0   | 
+---------+---------------+--------------+--------------+ 

よう

何かが私はオンライン周りを探してきた、「動的」クロス集計の列のリストを生成するものと思わdifficultです。私はむしろそれらをハードコードしたいと思いますが、とにかく日付のためにするのは変です。または、case with week numberのようなものを使用してください。

クロスタブ以外のソリューションを探すべきですか?すべてのヌルを含めて各ユーザーに一連の週を与えることができれば十分だと思います。今は私の参加戦略がそれを返すわけではないようです。

答えて

0

個人的に私は、日付ディメンションテーブルを使用し、そのテーブルをクエリの基礎として使用します。これらのタイプの計算に表形式のデータを使用するほうがはるかに簡単で、SQLの読み込みと保守が容易になります。 PostgreSQLにDate Dimensionテーブルを作成する方法については、https://medium.com/@duffn/creating-a-date-dimension-table-in-postgresql-af3f8e2941acという素晴らしい記事がありますが、もっと簡単なバージョンのこのテーブルを手に入れることはできます。

最終的には、SELECT cols FROM tableセクションのベースとして日付テーブルを使用して、これと結合するか、おそらくCommon Table Expressionsを使用して計算を作成します。

このようなクエリを作成する方法をデモンストレーションしたい場合は、その解決策を書き上げます。

関連する問題