2016-08-05 3 views
0

나는 그룹화 기준에 따라 그룹화 된 일부 날짜 및 시간 속성이있는 테이블을 보유하고 있고 일부는 집계하며, 쿼리는 지난 주 고객 당 수익을 얻는 것과 같습니다. 이제 요청 된 기간과 이전 기간 사이의 변경 사항을보고 싶습니다. 따라서 revenue 및 previous_revenue라는 두 개의 열이 생깁니다.다른 필드에 따라 집계 된 값

지금 당장 요청한 기간의 행에 이전 기간의 행을 더한 행을 요청하고 집계 된 각 필드에 대해 값을 반환하는 case 문을 추가하거나 원하는 기간에 0이 아닌 경우 0을 반환합니다.

집계 필드만큼 많은 사례가 있지만 항상 동일한 조건문을 사용합니다.

이 사용 사례에 대한 더 나은 디자인이 있는지 궁금 해요 ...

SELECT 
customer, 
SUM(
    CASE TIMESTAMP_CMP('2016-07-01 00:00:00', ft.date) > 0 WHEN true THEN 
    REVENUE 
    ELSE 0 END 
) AS revenue, 
SUM(
    CASE TIMESTAMP_CMP('2016-07-01 00:00:00', ft.date) < 0 WHEN true THEN 
    REVENUE 
    ELSE 0 END 
) AS previous_revenue 

WHERE date_hour >= '2016-06-01 00:00:00' 
AND date_hour <= '2016-07-31 23:59:59' 
GROUP BY customer 

답변

0

먼저 (내 실제 사용 사례에 나는 더 추악하게 많은 열이) , 타임 스탬프를 리팩토링하고 나중에 사용하기 위해 현재 및 이전 기간을 미리 계산하는 것이 좋습니다. 하지만 이것은 당신의 문제를 해결하기 위해 꼭 필요한 것은 : 이제

create temporary table _period as 
    select 
     '2016-07-01 00:00:00'::timestamp as curr_period_start 
     , '2016-07-31 23:59:59'::timestamp as curr_period_end 
     , '2016-06-01 00:00:00'::timestamp as prev_period_start 
     , '2016-06-30 23:59:59'::timestamp as prev_period_end 
; 

타임 스탬프의 반복과 CASE 문을 피하기 위해 가능한 디자인 첫 번째 기간에 의해 그룹이며, 다음 자체에 해당 테이블에 대한 FULL OUTER JOIN 일 :

with _aggregate as (
    select 
     case 
      when date_hour between prev_period_start and prev_period_end then 'previous' 
      when date_hour between curr_period_start and curr_period_end then 'current' 
     end::varchar(20) as period 
     , customer 
    -- < other columns to group by go here > 
     , sum(revenue)  as revenue 
    -- < other aggregates go here > 
    from 
     _revenue, _period 
    where 
     date_hour between prev_period_start and curr_period_end 
    group by 1, 2 
) 
select 
    customer 
    , current_period.revenue as revenue 
    , previous_period.revenue as previous_revenue 
from 
       (select * from _aggregate where period = 'previous') previous_period 
full outer join (select * from _aggregate where period = 'current') current_period 

using(customer) -- All columns which have been group by must go into the using() clause: 
       -- e.g. using(customer, some_column, another_column) 
; 
관련 문제