質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
BigQuery

BigQueryは、Google Cloud Platformが提供しているビッグデータ解析サービス。数TB(テラバイト)またはPB(ペタバイト)の膨大なデータに対し、SQL風のクエリを実行し、高速で集計・分析を行うサービスです。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Q&A

解決済

1回答

6576閲覧

日付毎にその日から一週間の間のアクティブユーザー数を集計したい

akm2929

総合スコア12

BigQuery

BigQueryは、Google Cloud Platformが提供しているビッグデータ解析サービス。数TB(テラバイト)またはPB(ペタバイト)の膨大なデータに対し、SQL風のクエリを実行し、高速で集計・分析を行うサービスです。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

0グッド

0クリップ

投稿2018/11/19 08:41

編集2018/11/21 06:02

完成イメージ↓

日付WAUMAU
2018/09/09200500
2018/09/10180480

WAU・・・日付−7日間の間に一度でもログインしたユニークユーザー数
MAU・・・日付−30日間の間に一度でもログインしたユニークユーザー数

何を使ってどう集計すればいいのでしょうか?
ちなみにDAUは以下のように出しています。

standardsql

1with T as ( 2 select 3 parse_date("%Y%m%d", event_date) event_date 4 , user_id 5 , event_name 6 from 7 `sample*` 8 where( 9 _TABLE_SUFFIX BETWEEN 10 "20180707" AND 11 FORMAT_DATE("%Y%m%d", DATE_SUB(CURRENT_DATE(), INTERVAL 1 DAY)) 12 ) 13 and 14 app_info.install_source = 'iTunes' 15 and 16 date(TIMESTAMP_ADD(timestamp_micros(user_first_touch_timestamp), interval device.time_zone_offset_seconds SECOND)) > "2018-07-06" 17 and 18 user_id is not null 19) 20 21,dau as ( 22 select 23 event_date 24 ,count(distinct(user_id)) as dau_count 25 from 26 T 27 group by 28 event_date 29)

user_idはイベント毎に計測されるため、元データでは重複があります。

<↓saziさんの回答を自分なりに解釈して書いたコード(コピペだとエラーで、saziさんの書き方が高度でどう変えればいいかわかりませんでした。。。)>
エラーはないのですが、dau、wau、mauの数字がほぼ同じになってしまいました。

standardsql

1with T as ( 2 select 3 parse_date("%Y%m%d", event_date) event_date 4 , user_id 5 , event_name 6 from 7 `sample*` 8 where( 9 _TABLE_SUFFIX BETWEEN 10 "20180707" AND 11 FORMAT_DATE("%Y%m%d", DATE_SUB(CURRENT_DATE(), INTERVAL 1 DAY)) 12 ) 13 and 14 app_info.install_source = 'iTunes' 15 and 16 date(TIMESTAMP_ADD(timestamp_micros(user_first_touch_timestamp), interval device.time_zone_offset_seconds SECOND)) > "2018-07-06" 17 and 18 user_id is not null 19 limit 10000000 20) 21 22, dau as ( 23 select 24 event_date 25 ,count(distinct(user_id)) as dau_count 26 from 27 T 28 group by 29 event_date 30) 31 32, wau as ( 33 select 34 event_date 35 ,count(distinct(user_id)) as wau_count 36 from 37 T 38 where 39 event_date between t.event_date and date_add(t.event_date,interval 7 day) 40 group by event_date 41) 42 43, mau as ( 44 select 45 event_date 46 ,count(distinct(user_id)) as mau_count 47 from 48 T 49 where 50 event_date between t.event_date and date_add(t.event_date,interval 1 month) 51 group by event_date 52) 53 54, before_formating as ( 55 select 56 dau.event_date 57 ,dau_count 58 ,wau_count 59 ,mau_count 60 from 61 dau 62 left join 63 wau 64 on 65 dau.event_date = wau.event_date 66 left join 67 mau 68 on 69 dau.event_date = mau.event_date 70) 71select * 72from before_formating 73order by event_date asc

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yambejp

2018/11/19 08:58 編集

Tテーブルのサンプルデータを提示して下さい。とくにuser_idはevent_date毎にユニークなのかそれとも1日何度もログインできるのか提示してください
akm2929

2018/11/19 09:03

すいません、追記させていただきました。user_idは一日に複数回カウントされます。不足失礼しました。
guest

回答1

0

ベストアンサー

試せてませんが、DATE_ADDを使用すると以下のようになるかと。

SQL

1 select event_date 2 , (select count(distinct(user_id)) from T 3 where event_date between t1.event_date and DATE_ADD(t1.event_date, INTERVAL -7 DAY)) 4 ) as wau_count 5 , (select count(distinct(user_id)) from T 6 where event_date between t1.event_date and DATE_ADD(t1.event_date, INTERVAL -1 MONTH)) 7 ) as mau_count 8from ( 9 select event_date 10 from T 11 group by event_date 12) t1

追記

追加された記述より展開

SQL

1with T as ( 2 select 3 date(event_date) event_date 4 , user_id 5 , event_name 6 from 7 `sample*` 8 where( 9 _TABLE_SUFFIX BETWEEN 10 "20180707" AND 11 FORMAT_DATE("%Y%m%d", DATE_SUB(CURRENT_DATE(), INTERVAL 1 DAY)) 12 ) 13 and 14 app_info.install_source = 'iTunes' 15 and 16 date(TIMESTAMP_ADD(timestamp_micros(user_first_touch_timestamp), interval device.time_zone_offset_seconds SECOND)) > "2018-07-06" 17 and 18 user_id is not null 19 limit 10000000 20) 21, dau as ( 22 select 23 event_date 24 ,count(distinct(user_id)) as dau_count 25 from 26 T 27 group by 28 event_date 29) 30, base_date as( 31 select event_date from T group by event_date 32 ) 33 34, wau as ( 35 select 36 base_date.event_date 37 , count(distinct(T.user_id)) as wau_count 38 from base_date inner join T 39 on T.event_date between base_date.event_date and date(date_add(date base_date.event_date,interval 7 day)) 40 group by base_date.event_date 41) 42, mau as ( 43 select 44 base_date.event_date 45 , count(distinct(T.user_id)) as wau_count 46 from base_date inner join T 47 on T.event_date between base_date.event_date and date(date_add(date base_date.event_date,interval 1 month)) 48 group by base_date.event_date 49) 50, before_formating as ( 51 select 52 dau.event_date 53 ,dau_count 54 ,wau_count 55 ,mau_count 56 from 57 dau 58 left join 59 wau 60 on 61 dau.event_date = wau.event_date 62 left join 63 mau 64 on 65 dau.event_date = mau.event_date 66) 67select * 68from before_formating 69order by event_date asc

BigQueryでは相関問い合わせは使用しない方が良いみたいですね。
BigQueryで相関サブクエリがうまく動かなかった話

追記

予め、範囲となる日付を求めておくように修正

SQL

1with T as ( 2 select 3 date(event_date) event_date 4 , date(date_add(event_date,interval 7 day)) wau_range_date 5 , date(date_add(event_date,interval 1 month)) mau_range_date 6 , user_id 7 , event_name 8 from `sample*` 9 where (_TABLE_SUFFIX BETWEEN "20180707" AND FORMAT_DATE("%Y%m%d", DATE_SUB(CURRENT_DATE(), INTERVAL 1 DAY))) 10 and app_info.install_source = 'iTunes' 11 and date(TIMESTAMP_ADD(timestamp_micros(user_first_touch_timestamp), interval device.time_zone_offset_seconds SECOND)) > "2018-07-06" 12 and user_id is not null 13 limit 10000000 14) 15, dau as ( 16 select 17 event_date 18 ,count(distinct(user_id)) as dau_count 19 from 20 T 21 group by 22 event_date 23) 24, base_date as( 25 select event_date from T group by event_date 26 ) 27 28, wau as ( 29 select 30 base_date.event_date 31 , count(distinct(T.user_id)) as wau_count 32 from base_date inner join T 33 on base_date.event_date between T.event_date and T.wau_range_date 34 group by base_date.event_date 35) 36, mau as ( 37 select 38 base_date.event_date 39 , count(distinct(T.user_id)) as wau_count 40 from base_date inner join T 41 on base_date.event_date between T.event_date and T.mau_range_date 42 group by base_date.event_date 43) 44, before_formating as ( 45 select 46 dau.event_date 47 ,dau_count 48 ,wau_count 49 ,mau_count 50 from 51 dau 52 left join 53 wau 54 on 55 dau.event_date = wau.event_date 56 left join 57 mau 58 on 59 dau.event_date = mau.event_date 60) 61select * 62from before_formating 63order by event_date asc

単にユーザーのIDをカウントするだけなので、シンプルになりそう。

SQL

1with T as ( 2 select 3 date(event_date) event_date 4 , date(date_add(event_date,interval 7 day)) wau_range_date 5 , date(date_add(event_date,interval 1 month)) mau_range_date 6 , user_id 7 , event_name 8 from `sample*` 9 where (_TABLE_SUFFIX BETWEEN "20180707" AND FORMAT_DATE("%Y%m%d", DATE_SUB(CURRENT_DATE(), INTERVAL 1 DAY))) 10 and app_info.install_source = 'iTunes' 11 and date(TIMESTAMP_ADD(timestamp_micros(user_first_touch_timestamp), interval device.time_zone_offset_seconds SECOND)) > "2018-07-06" 12 and user_id is not null 13 limit 10000000 14) 15select 16 dau.event_date 17 , count(distinct(dau.user_id)) as dau_count 18 , count(distinct(wau.user_id)) as wau_count 19 , count(distinct(mau.user_id)) as mau_count 20from T as dau 21 inner join T as wau 22 on dau.event_date between wau.event_date and wau.wau_range_date 23 inner join T as mau 24 on dau.event_date between mau.event_date and mau.wau_range_date 25group by dau.event_date 26order by dau.event_date asc 27

投稿2018/11/19 09:04

編集2018/11/22 00:32
sazi

総合スコア25193

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

akm2929

2018/11/21 05:59

ご回答ありがとうございます。 初心者でして、saziさんの書き方がどういうロジックになっているのかわからず、自分なりにやってみたのですが(質問文内に追記させていただきました)、エラーはでないのですが、dau、wau、mauがほぼ同じ数字になってしまいました。 どこがだめでどうすればいいのかがわかりません… よろしければご指導いただけると幸いです。 (saziさんの書き方が高度すぎたので、一応コピペは試してはみたのですが、コピペだとやはりエラーでした。)
sazi

2018/11/21 07:27 編集

最終的なbefore_formatingのwau_countやmau_countはそのevent_dateを基準にした範囲の集計である必要があります。 withでそれぞれ計算されているのは、範囲は指定されていますが、結局event_date毎にしか集計されていませんね。
sazi

2018/11/21 07:27

コピペした時のエラーはどういった内容ですか? DATE_ADDはTIMESTAMP型でないと駄目なので、そのエラーでしたら変換を掛ければ良いと思います。
akm2929

2018/11/21 08:35

```with T as ( select parse_date("%Y%m%d", event_date) event_date , user_id , event_name from `sample*` where( _TABLE_SUFFIX BETWEEN "20180707" AND FORMAT_DATE("%Y%m%d", DATE_SUB(CURRENT_DATE(), INTERVAL 1 DAY)) ) and app_info.install_source = 'iTunes' and date(TIMESTAMP_ADD(timestamp_micros(user_first_touch_timestamp), interval device.time_zone_offset_seconds SECOND)) > "2018-07-06" and user_id is not null limit 10000000 ) , dau as ( select event_date ,count(distinct(user_id)) as dau_count from T group by event_date ) select event_date , (select count(distinct(user_id)) from T where event_date between t1.event_date and DATE_ADD(t1.event_date, INTERVAL -7 DAY)) as wau_count , (select count(distinct(user_id)) from T where event_date between t1.event_date and DATE_ADD(t1.event_date, INTERVAL -1 MONTH)) as mau_count from ( select event_date from T group by event_date ) t1``` このコードで試し、 Error running query: LEFT OUTER JOIN cannot be used without a condition that is an equality of fields from both sides of the join. というエラーがでてきました…
sazi

2018/11/21 08:47

そのSQLは全文じゃないでしょう? エラーであるleft join はどこにも使用されていませんから
sazi

2018/11/21 08:48

あ、サブクエリーで出ているみたいですね。 ちょっと待って下さいね。
akm2929

2018/11/21 08:50

私もそう思ったのですが、withTから始まるこれが全文になります… 実物と変えた点は、 `sample*` の部分のみになります。
akm2929

2018/11/21 08:52

ありがとうございます…!
akm2929

2018/11/22 08:23

詳細な回答ありがとうございました!!
sazi

2018/11/22 08:28

最後ので、上手くいきましたか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問