2017-05-22 6 views
0

dense_rank()などを使用して月ごとに別のものを数える方法についてはかなりの量がありますが、私はもまた別のものを見つけることができませんでした先月のグループで見られた。レッド・シフトで月に一度「真新しい、見たことのない」IDを数えることができますか?

データがそうのように想像することができます。

id (int8 type) | observed time (timestamp utc) 
------------------ 
1 | 2017-01-01 
2 | 2017-01-02 
1 | 2017-01-02 
1 | 2017-02-02 
2 | 2017-02-03 
3 | 2017-02-04 
1 | 2017-03-01 
3 | 2017-03-01 
4 | 2017-03-01 
5 | 2017-03-02 

数のプロセスのように見ることができます。

1:2017から01に、我々は、デバイス1と2を見たので、カウントは2であります

2:2017から03に、我々は、デバイスを見た:2017から02に、私たちは私たちは、デバイス1と2について既に知っているではなく、3、その数は1

3であるデバイス1、2と3を見ました1、3、4および5約1〜3ではなく4または5知っているので、カウントは、所望の出力のようなものであることを2

です:明示的に、私は、新しいテーブルを持って探しています

observed time | count of new id 
-------------------------- 
2017-01  | 2 
2017-02  | 1 
2017-03  | 2 

1か月あたり集計された月と、その月に発生した新しいIDの数が、以前はまったく見られなかった回数で計算されます。

IRLの場合、デバイスは1か月に複数回表示されますが、カウントには影響しません。また、idの格納に正の整数と負の整数を使用し、真のタイムスタンプでは2番目の時間になります。データセットのサイズも重要です。

私の最初の試みは、のラインに沿っている:

WITH records_months AS (
SELECT *, 
date_trunc('month', observed_time) AS month_group 
FROM my_table 
WHERE observed_time > '2017-01-01') 
id_months AS (
SELECT DISTINCT 
month_group, 
id 
FROM records_months 
GROUP BY month_group, id) 
SELECT * 
FROM id-months 

しかし、私は前にヶ月で見られなかった新しいIDの数をカウントすなわち次の部分にこだわっています。私はこのソリューションが窓関数かもしれないと信じていますが、どのように、どのようにして解決するのか困っています。

答えて

2

私が考えた最初のこと。アイデアは

  • にある(最も内側のクエリ)、各idが見られたことを早い月計算
  • (次のレベルアップ)(外部クエリ)メインmy_tableデータセットにそれをバックに参加し、その後
  • 既に確認されているidを無効にした後、月別にidを数えます。

私はそれをテストし、望ましい結果セットを得ました。最も早い月に元のテーブルに戻ってくることは、(ウィンドウ関数に対して)最も自然なことでした。うまくいけば、これはRedshiftのために十分なパフォーマンスです!

select observed_month, 
    -- Null out the id if the observed_month that we're grouping by 
    -- is NOT the earliest month that the id was seen. 
    -- Then count distinct id 
    count(distinct(case when observed_month != earliest_month then null else id end)) as num_new_ids 
from (
    select t.id, 
     date_trunc('month', t.observed_time) as observed_month, 
     earliest.earliest_month 
    from my_table t 
     join (
      -- What's the earliest month an id was seen? 
      select id, 
       date_trunc('month', min(observed_time)) as earliest_month 
      from my_table 
      group by 1 
     ) earliest 
     on t.id = earliest.id 
) 
group by 1 
order by 1; 
+0

ありがとうございます。私はこれが正しいと信じています。私の現在のIRLデータセットに対する私の要求にも十分に速いです。 – DaveRGP

関連する問題