2016-04-26 7 views
2

私はあるページの訪問者の数を格納するテーブル(view_of_referred_events)を持っています。現在の日付が失われている場合、30日の移動/移動合計

date  country_id referral product_id visitors 
2016-04-01 216   pl   113759  1 
2016-04-03 216   pl   113759  1 
2016-04-06 216   pl   113759  13 
2016-04-07 216   pl   113759  10 

この商品の30日間の移動/移動合計は、欠落している場合でも計算したいと考えています。私は別のcountry_idreferralproduct_idの数十を持っているので、

date  country_id referral product_id cumulative_visitors 
2016-04-01 216   pl   113759  1 
2016-04-02 216   pl   113759  1 
2016-04-03 216   pl   113759  2 
2016-04-04 216   pl   113759  2 
2016-04-05 216   pl   113759  2 
2016-04-06 216   pl   113759  15 
2016-04-07 216   pl   113759  25 

さて、これは単純化した表現は、次のとおりです。だから、最終的な結果は以下のようなものでなければなりません。 {datecountry_idreferralproduct_id}の可能なすべての組み合わせを持つテーブルを事前に作成することはできません。これは、テーブルのサイズを考えると無意味になるためです。特定の{date,country_id,referralおよびproduct_id}が以前に存在しなかった場合、私は最終表に1列あることも望んでいません。

view_of_referred_eventsにその日の訪問者がいない場合、前の行(前日)の値を使用するようにImpalaに指示する簡単な方法があれば、私は考えていました。

私はこのクエリを書いています。list_of_datesは、4月1日から4月7日までの日数の一覧表です。

select 
    t.`date`, 
    t.country_id, 
    t.referral, 
    t.product_id, 
    sum(visitors) over (partition by t.country_id, t.referral, t.product_id order by t.`date` 
        rows between 30 preceding and current row) as cumulative_sum_visitors 
from (
    selec 
    d.`date`, 
    re.country_id, 
    re.referral, 
    re.product_id, 
    sum(visitors) as visitors 
    from list_of_dates d 
    left outer join view_of_referred_events re on d.`date` = re.`date` 
    and re.referral = "pl" 
    and re.product_id = "113759" 
    and re.country_id = "216" 
    group by d.`date`, re.country_id, re.referral, re.product_id 
) t 
order by t.`date` asc; 

これは、私が欲しいものに似ていますが、正確ではありません。

date  country_id referral product_id cumulative_visitors 
2016-04-01 216   pl   113759  1 
2016-04-02 NULL  NULL  NULL  NULL 
2016-04-03 216   pl   113759  2 
2016-04-04 NULL  NULL  NULL  NULL 
2016-04-05 NULL  NULL  NULL  NULL 
2016-04-06 216   pl   113759  15 
2016-04-07 216   pl   113759  25 
+0

明確にしてください:あなたのテキストとタイトルが累積和に関するものです。クエリでは、30日の移動/移動合計が必要です。 –

答えて

0

私はパフォーマンスがなりグーかどうかはわかりませんが、あなたは2倍のデータを集約し、第2の集約のために30日間の追加、カウントを否定することによってこれを行うことができます。このような

何か:私は、パーティション内の最後の行から値を取得するために別のサブクエリを追加した

with t as (
     select d.`date`, re.country_id, re.referral, re.product_id, 
      sum(visitors) as visitors 
     from list_of_dates d left outer join 
      view_of_referred_events re 
      on d.`date` = re.`date` and 
       re.referral = 'pl' and 
       re.product_id = 113759 and 
       re.country_id = 216 
     group by d.`date`, re.country_id, re.referral, re.product_id 
    ) 
select date, country_id, referral, product_id, 
     sum(sum(visitors)) over (partition by country_id, referral, product_id order by date) as visitors 
from ((select date, country_id, referral, product_id, visitors 
     from t 
    ) union all 
     (select date_add(date, 30), country_id, referral, product_id, -visitors 
     from t 
    ) 
    ) tt 
group by date, country_id, referral, product_id; 
+0

't'を定義すると、' GROUP BY d.'date'、re.country_id、re.referral、re.product_id'を忘れたと思います。それに加えて、このクエリは訪問者がいない当時の値を引き継ぎません。当時、 'country_id'、' referral'、 'product_id'、' visitors'の値は 'NULL'になります。 – Gianluca

+0

@Gianluca。 。 。ありがとうございました。第二のポイントは、あなたが変わらない日を望んでいないと思った。 –

0

。あなたが使用しているハイブ/インパラのバージョンがわからないのですが、last_value(column_name, ignore null values true/false)が構文です。

私はあなたが30日(月)以上の累積カウントを見つけようとしていると仮定して、月フィールドを使用して行をグループ化することをお勧めします。その月は、ディメンションテーブルlist_of_datesまたはsubstr(date, 1, 7)から来て、..rows unbounded preceding and current rowを超える訪問者の累積カウントを取得することができます。

クエリ:

select 
    `date`, 
    country_id, 
    referral, 
    product_id, 
    sum(visitors) over (partition by country_id, referral, product_id order by `date` 
        rows between 30 preceding and current row) as cumulative_sum_visitors 
from (select 
    t.`date`, 
    -- get the last not null value from the partition window w for country_id, referral & product_id 
    last_value(t.country_id, true) over w as country_id, 
    last_value(t.referral, true) over w as referral 
    last_value(t.product_id, true) over w as product_id 
    if(visitors = null, 0, visitors) as visitors 
from (
    select 
    d.`date`, 
    re.country_id, 
    re.referral, 
    re.product_id, 
    sum(visitors) as visitors 
    from list_of_dates d 
    left outer join view_of_referred_events re on d.`date` = re.`date` 
    and re.referral = "pl" 
    and re.product_id = "113759" 
    and re.country_id = "216" 
    group by d.`date`, re.country_id, re.referral, re.product_id 
) t 
window w as (partition by t.country_id, t.referral, t.product_id order by t.`date` 
        rows between unbounded preceding and unbounded following)) t1 
order by `date` asc; 
+0

残念ながら、現在のバージョンのImpalaでは、 'LAST_VALUE'関数の' NULL'値を無視することはできません。 – Gianluca

関連する問題