2016-11-18 8 views
0

私はデータベース内の顧客の接続ログテーブルを持っており、前の7日間に各顧客が行った接続数を毎日計算しています。私が使用しているソーステーブルは、出力が末尾のX日間のセッション数をカウントする

uuid, _date, total_connections_over_trailing_seven_days, 

私は何回あの人、特定の顧客口座と、指定した日付のために見ることができるようにあるように私が欲しいもの

uuid, sessionuid, connection_timestamp 

のスキーマを持っています過去7日(またはそれ以前)に接続しています。

私はこれを達成するために書かれているクエリが

SELECT 
    uuid, 
    connection_timestamp::date as _date, 
    COUNT(sessionuid) OVER (ORDER BY timestamp_session ROWS 6 PRECEDING) as trailing_seven_day_session_count 
FROM connection_history_table 

あるしかし、私はこのクエリを実行すると、私は、ユーザーごとに個別のラインとそれぞれの固有のための代わりに単一のレコードのソーステーブル内のすべてのconnection_timestampを取得しますconnection_timestamp :: date。さらに、trailing_seven_day_session_countの値は1から最大値7(ある日に少なくとも7つのセッションがある場合)に増加しますが、それ以降は増加しません。だから、私は特定の日にセッションの数を数えているようですが、最初の7セッションでのみです。

uuid  _date    trailing_seven_day_session_count 
16398 2015-02-18 00:00:00 1 
16398 2015-02-18 00:00:00 2 
16398 2015-02-18 00:00:00 3 
16398 2015-02-18 00:00:00 4 
16398 2015-02-18 00:00:00 5 
16398 2015-02-18 00:00:00 6 
16398 2015-02-18 00:00:00 7 
16398 2015-02-18 00:00:00 8 
16398 2015-02-18 00:00:00 8 
16398 2015-02-25 00:00:00 1 
16398 2015-02-25 00:00:00 2 
16398 2015-02-25 00:00:00 3 
16398 2015-02-25 00:00:00 4 
16398 2015-02-25 00:00:00 5 
16398 2015-02-25 00:00:00 6 
16398 2015-02-25 00:00:00 7 
16398 2015-02-25 00:00:00 8 
16398 2015-02-25 00:00:00 8 

ここで私が間違っていることは私には分かりません。私はconnection_timestamp :: dateでパーティションを実行しようとしましたが、それはどちらも助けにはなりませんでした。私は基本的にはストローで握っている、とうまくいかない。

おかげで、 ブラッド

答えて

1

はたぶん、あなたは毎日のセッションをカウントして、前の日の合計を行う必要があります。このようなもの:

select 
    uuid, 
    day, 
    sum(sessions) over (partition by uuid order by day rows 6 preceding) as trailing_seven_day_session_count 
from (select uuid, connection_timestamp::date as day, count(*) sessions 
    from connection_history_table 
    group by 1,2) 
order by 1,2 

スパースデータについてのBradのコメントについては、ここに可能なアプローチがあります。日数を埋めるためにゼロレコードを生成するので、設定されたレコード数を振り返ると、日数に相関します。これを実行していないが、それはかなり近いはずです。日数が発生するため、全体の時間範囲を調整する必要があります。私は、曜日の範囲とパディングが正しいかどうかはわかりません。30日分のレコードを生成するために、37日間分のデータを取得しようとしています。

with days as (
    -- hack to generate days in redshift like a generate_series function 
    select (dateadd(day, -row_number() over (order by true), sysdate::date)) as day 
      from stv_blocklist limit 37 
), 
day_counts as (
    select uuid, connection_timestamp::date as day, count(*) sessions 
    from connection_history_table 
    where connection_timestamp >= sysdate-37 
    group by 1,2 
), 
zero_days as (
    select s.uuid, d.day, 0 as sessions 
    from (
     select distinct uuid from connection_history_table 
     where connection_timestamp >= sysdate-37 
    ) s 
    cross join days d 
) 
select 
    uuid, 
    day, 
    sum(sessions) over (partition by uuid order by day rows 6 preceding) as trailing_seven_day_session_count 
from (
    select uuid, day, sessions from day_counts 
    union all 
    select uuid, day, sessions from zero_days z 
     left join day_counts c on z.uuid=c.uuid and z.day=c.day 
     where c.uuid is null 
) 
having day >= sysdate-30 
order by 1,2 
+0

ええ、私はそのような何かをしようとしたが、それは前の6行の上にカウントされるため、それは私が欲しいものを非常に取得していない、と私は必ずしも日常の行を持っていません。私は、ユーザーが演奏した毎日の行しか持っていません。だから私はまったく別の解決策を考え出す必要があります。あなたの助けをありがとう。私はあなたのソリューションをupvoteし、私が実際に持っている問題ではなく、私が投稿した元の問題を解決するので、それを受け入れるつもりです。 : –

+0

一度のショットでなければならないのでしょうか、それとも繰り返しクエリを実行できますか?一日一回ですか?毎日行うことができれば、あなたが望むものを得るためにconnection_timestamp> = sysdate-7のレコードだけを選択する内側のselectにwhere句を追加することができます。 – systemjack

+0

null日を処理するjankyクエリが追加されました。 – systemjack

関連する問題