68756


## やりたいこと

Userが例えば `生まれた年(=year)`と`出身の都道府県(:prefecture_id)`カラムを持っているとします。

そこから 「同じ生まれ年」かつ「同じ出身都道府県」のユーザーが3人以上いる場合、そのユーザーの一覧を取得したいです。

出力結果がHashであるため期待する結果ではないのですが、集計して多い順に並び替える処理は以下で出来ました。

[code]

    User.group(:year, :prefecture_id).having("count_all > 3").order("count_all DESC").count
    
[/code]

この出力結果は `{[1990, 13]=>4, [1996,2]=>3}` のように、生まれ年と都道府県ID、一致した数になっています。

ここから、この「生まれ年」と「都道府県ID」を持つユーザーを一覧を取得するにはどのような手段がありますでしょうか？

* * *

上でのHashにUserIdがあれば、pluckとwhereを用いて取得することも出来るかと思いましたが、Idがあると適切なGroupにならないためそれも出来なかったです。。

## 試したこと

パフォーマンスは悪いですが、以下などが一応期待した動作でした。  
しかしデータ数が10万件とかなるとパフォーマンスが非常に悪いため避けたいと思っています。

[code]

    user_hash = User.all.group_by{ |user| [ user[:year], user[:prefecture_id] ] }
    @users = user_hash.values.select{ |user| 3 < user.size }
    
[/code]


CC BY-SA 4.0
2020-07-20T11:31:21.497
68754
2020-07-21T03:56:06.923
2020-07-20T11:39:32.223
3060
40498
question
ruby-on-rails mysql
複数カラムでGroupした結果をHashでなくActiveRecord::relationで取得したい

[code]

    User.joins(<<~SQL)
      INNER JOIN (
        #{User.select("year, prefecture_id, count(*) as count_all").group(:year, :prefecture_id).having("count_all > ?", 3).to_sql}
      ) as year_pref
      ON users.year = year_pref.year
      AND users.prefecture_id = year_pref.prefecture_id
    SQL
    
[/code]

のようにすると、望みの User についての relation が得られるのではないか、と思っていますが、いかがでしょうか?

# 追記@2020/07/21

「該当件数」でソートしたい場合には、 sort 条件を relation に含めれば良いと思っています。 e.g.

[code]

    User.joins(<<~SQL).order("year_pref.count_all DESC")
      INNER JOIN (
        #{User.select("year, prefecture_id, count(*) as count_all").group(:year, :prefecture_id).having("count_all > ?", 3).to_sql}
      ) as year_pref
      ON users.year = year_pref.year
      AND users.prefecture_id = year_pref.prefecture_id
    SQL
    
[/code]


CC BY-SA 4.0
2020-07-20T13:12:50.980
68756
2020-07-21T03:56:06.923
2020-07-21T03:56:06.923
754
754
68754
answer