回答編集履歴

2 追記

sazi

sazi score 19516

2020/07/09 09:55  投稿

> 月のデータを作成してjoinしてみましたが、各ユーザーごとの集計にはできませんでした。
> (月のデータがuser_idをもっていないので。)
そのデータを生成しましょう。
直積(cross join)で全ての組み合わせを取得します。  
```SQL
select user_id, 日付
from (
      select user_id
      from user_data
      group by user_id
    ) cross join 月のデータ
```
※user_dataに求めたいuser_idが全て含まれていることが前提です。
 他にデータがあるなら(ユーザーのマスタとか)それを使用して下さい。
後は、繋ぐだけですね。
```SQL
select coalesce(arg.cnt, 0) , base.*
from (
       select user_id, 日付
       from (
              select user_id
              from user_data
              group by user_id
            ) usr cross join 月のデータ
    ) base left join
       select count(*) as cnt
            , user_id
            , date_format(update_date, '%Y-%m') as u_date
       from user_data
       where 1 = 1
       group by user_id, date_format(update_date, '%Y-%m')
    ) arg
    on base.user_id=arg.user_id and base.日付=arg.u_date
order by base.user_id, base.日付
```
1 追記

sazi

sazi score 19516

2020/07/09 09:53  投稿

> 月のデータを作成してjoinしてみましたが、各ユーザーごとの集計にはできませんでした。
> (月のデータがuser_idをもっていないので。)
そのデータを生成しましょう。
```SQL
select user_id, 日付
from (
      select user_id
      from user_data
      group by user_id
    ) cross join 月のデータ
```
※user_dataに求めたいuser_idが全て含まれていることが前提です。  
 他にデータがあるなら(ユーザーのマスタとか)それを使用して下さい。  
 
後は、繋ぐだけですね。
```SQL
select coalesce(arg.cnt, 0) , base.*
from (
       select user_id, 日付
       from (
              select user_id
              from user_data
              group by user_id
            ) usr cross join 月のデータ
    ) base left join
       select count(*) as cnt
            , user_id
            , date_format(update_date, '%Y-%m') as u_date
       from user_data
       where 1 = 1
       group by user_id, date_format(update_date, '%Y-%m')
    ) arg
    on base.user_id=arg.user_id and base.日付=arg.u_date
order by base.user_id, base.日付
```

思考するエンジニアのためのQ&Aサイト「teratail」について詳しく知る