【Rails】GROUP BY句で外部キーを指定したところ、ActiveRecord::StatementInvalidになる
目次
外部キーのグループ化で、地味に躓いたので記事としてまとめます!
問題
GROUP BY句で外部キーを指定して、インスタンスを取り出そうとするとエラーが起きました。
現象
①
groupメソッドで、外部キーであるオフィスIDを指定し、条件に該当するインスタンスを複数得ることができます。
ここまではエラーは発生しません。
1 2 3 |
User.group(:office_id).select(:office_id) User Load (9.7ms) SELECT <code>users</code>.<code>office_id</code> FROM <code>users</code> GROUP BY <code>users</code>.<code>office_id</code> LIMIT 11 => #<ActiveRecord::Relation [#<User id: nil, office_id: 1>, #<User id: nil, office_id: 3>, #<User id: nil, office_id: 4>, #<User id: nil, office_id: 6>, #<User id: nil, office_id: 7>, #<User id: nil, office_id: 8>, #<User id: nil, office_id: 9>, #<User id: nil, office_id: 10>, #<User id: nil, office_id: 11>, #<User id: nil, office_id: 12>, ...]> |
②
次に、インスタンスを取り出そうとすると、この段階でエラーが発生する。
1 2 3 4 5 |
User.group(:office_id).select(:office_id).first User Load (8.9ms) SELECT <code>users</code>.<code>office_id</code> FROM <code>users</code> GROUP BY <code>users</code>.<code>office_id</code> ORDER BY <code>users</code>.<code>id</code> ASC LIMIT 1 Traceback (most recent call last): 1: from (irb):23 ActiveRecord::StatementInvalid (Mysql2::Error: Expression #1 of ORDER BY clause is not in GROUP BY clause and contains nonaggregated column ‘rd_web_office_app.users.id’ which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by) |
調査
エラーが起きた時のSQLをみていきます。
1 |
SELECT <code>users</code>.<code>office_id</code> FROM <code>users</code> GROUP BY <code>users</code>.<code>office_id</code> ORDER BY <code>users</code>.<code>id</code> ASC LIMIT 1 |
→意図せず、デフォルトでusersテーブルの主キーである、IDでsortしようとしていました。
1 |
ORDER BY <code>users</code>.<code>id</code> |
回避方法
明示的に、値の存在する外部キーでsortすることで、インスタンスを取り出すことができました!
1 2 3 |
User.group(:office_id).select(:office_id).order(:office_id).first User Load (7.6ms) SELECT <code>users</code>.<code>office_id</code> FROM <code>users</code> GROUP BY <code>users</code>.<code>office_id</code> ORDER BY <code>users</code>.<code>office_id</code> ASC LIMIT 1 => #<User id: nil, office_id: 1> |
最後に
挙動としては、デフォルトで主キーsortされることでエラーになっていました。
外部キーのグループ化では気をつけたいです!