2016-10-12 9 views
0

で最低のタイムスタンプを持つ行の数、私は次のようしている:SQL:私のハイブテーブルでハイブ

mydate,user_id,source,timestamp 
20160901,10293,google,2016-09-01 00:21:06 
20160901,34393,yelp,2016-09-01 05:23:00 
20160901,38437,fb,2016-09-01 12:03:24 
20160902,34393,google,2016-09-02 13:44:55 

...

ソースは、ユーザの紹介の場所を示し、から得ることができますyelp、google、fb、bingなど - この紹介は、ユーザーがどのような種類のアカウントを持っているかを示します。 user_idはテーブル全体で一意で、私は過去1年間のソースの分布を見つけようとしています。

私はしかし、ここでの合併症は、ユーザーが自分のアカウントの種類を切り替えることができるということです

sum(IF(source = 'fb',1,0)) fb_count, 
sum(IF(source = 'yelp',1,0)) yelp_count 
... from my_table where mydate between blah and foo. 

ような何かを行うことができます。たとえば、ユーザーは、自分のアカウントが作成された後、ユーザーの種類を(たとえば)googleからbingに切り替えることができます。したがって、これを修正するには、テーブルの最初のタイムスタンプに対応するソースを選択する必要があります。これはユーザーアカウントが作成された時刻に対応します。

基本的には、カウントが行われる各ユーザータイプのカウントを、そのuser_idの最も低いタイムスタンプに対して検索します。参加それはかなり高価である私は自己を使用することができます...

month,fb_count,google_count,yelp_count,bing_count 
201601,1667,3403,304,4340 
201602,367,343,34,434 

を:

結果は次のようになります。より良い方法がありますか?

+0

結果はどのように見えるのですか? –

+0

@vkp質問を編集 – Craig

答えて

1

row_numberウィンドウ関数を使用してユーザーの最初の登録時刻を取得し、条件付き集計を使用できます。

select year(mydate),month(mydate), 
sum(IF(source = 'fb',1,0)) fb_count, 
sum(IF(source = 'yelp',1,0)) yelp_count 
from (select t.*, row_number() over(partition by user_id order by timestamp) rn 
     from tablename t) x 
where rn = 1 --add a date filter if necessary 
group by year(mydate),month(mydate) 
+0

すごくうまくいった。ありがとう! – Craig

関連する問題