2017-11-17 18 views
0

"시간 항목"테이블에서 각 사용자에 대한 주별 합계 보고서를 만들려고합니다. 테이블의PostgreSQL Crosstab generate_series columns에 대한 주 번호

샘플 :

+-----+---------+-------------------------+--------------+ 
| 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 

을 필요 얻을이다 특히 일주일 동안 데이터가없는 경우 분석하기가 어렵습니다. 필자가 원하는 것은 주가 열이고 행이 사용자 인 피벗 또는 크로스 탭 테이블입니다. 그리고 각각의 nulls를 포함합니다 (예를 들어, 사용자가 해당 주 또는 주에 항목이없고 사용자가 입력하지 않은 경우). 이

+---------+---------------+--------------+--------------+ 
| 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

개인적으로 나는 Date Dimension 테이블을 사용하고 해당 테이블을 쿼리의 기초로 사용합니다. 이러한 유형의 계산을 위해 표 형식의 데이터를 사용하는 것이 훨씬 쉽고 읽기 쉽고 유지하기 쉬운 SQL로 연결된다는 것을 알게되었습니다. PostgreSQL에 Date Dimension 테이블을 만드는 방법에 대한 훌륭한 기사가 있습니다 (https://medium.com/@duffn/creating-a-date-dimension-table-in-postgresql-af3f8e2941ac).하지만이 테이블을 훨씬 단순하게 만들 수는 있습니다.

궁극적으로 날짜 테이블을 SELECT cols FROM table 섹션의 기본으로 사용하고 그 테이블에 조인하거나 공통 테이블 식을 사용하여 계산을 작성하는 것입니다.

그런 쿼리를 어떻게 만들 수 있는지 설명하고 싶다면이 솔루션을 작성하겠습니다.