2016-08-05 18 views
0

私はグループ化されたいくつかの日時と複数のプロパティを持つテーブルを持っており、集計するものもあります。クエリは先週の顧客1人当たりの収益を得るようなものになります。 これで、要求された期間と以前の期間との間の変更を確認したいので、私は2列のrevenueとprevious_revenueを持ちます。他のフィールドに応じた集計値

今は要求期間の行に前期間の行を加えたものを要求しています。集約フィールドごとに、値を返すcase文を追加します。そうでない場合は0を返します。

これは、集約フィールドと同じ数のCASEを導きますが、常に同じ条件文を持ちます。

このユースケースのためのより良い設計がある場合、私は思ったんだけど...

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) 
; 
関連する問題