私はこのエラーをpgプロダクションモードで取得していますが、sqlite3開発モードでは問題なく動作します。
ActiveRecord::StatementInvalid in ManagementController#index
PG::Error: ERROR: column "estates.id" must appear in the GROUP BY clause or be used in an aggregate function
LINE 1: SELECT "estates".* FROM "estates" WHERE "estates"."Mgmt" = ...
^
: SELECT "estates".* FROM "estates" WHERE "estates"."Mgmt" = 'Mazzey' GROUP BY user_id
@myestate = Estate.where(:Mgmt => current_user.Company).group(:user_id).all
@myestate1 = Estate.where(:Mgmt => current_user.Company)
@myestate = @myestate1.select("DISTINCT(user_id)")
これは私がやったことです。
user_id
がPRIMARY KEYの場合、PostgreSQLをアップグレードする必要があります。新しいバージョンでは、主キーによるグループ化が正しく処理されます。
user_id
が一意でもない場合nor問題の 'estates'関係の主キーは、このクエリはあまり意味がありません。 PostgreSQLには、複数の行が同じuser_id
を共有するestates
の各列に対して返す値whichを知る方法がありません。 min
、max
、avg
、string_agg
、array_agg
など、必要なものを表す集約関数を使用するか、列を追加する必要があります。 )GROUP BY
に関心があります。
あるいは、本当に任意の行を選択する必要がある場合は、DISTINCT ON
とORDER BY
を使用するようにクエリを言い換えることができますが、ActiveRecordを使用してそれを表現することはできません。
SQLiteやMySQLなどの一部のデータベースは、任意の行を選択するだけです。これはPostgreSQLチームによって不正確で安全でないと見なされているため、PostgreSQLはSQL標準に従っており、そのようなクエリはエラーであると見なします。
あなたが持っている場合:
col1 col2
fred 42
bob 9
fred 44
fred 99
そしてあなたはする:
SELECT col1, col2 FROM mytable GROUP BY col1;
行を取得する必要があることは明らかです。
bob 9
しかし、fred
の結果はどうですか?選択する正しい答えは1つもないため、データベースはこのような安全でないクエリの実行を拒否します。任意のcol2
に対してgreatestcol1
が必要な場合は、max
集計を使用します。
SELECT col1, max(col2) AS max_col2 FROM mytable GROUP BY col1;
私は最近、MySQLからPostgreSQLに移行し、同じ問題に遭遇しました。参考までに、私が見つけた最良のアプローチは、このSO answer:
for Ruby on Rails/ActiveRecord によるエレガントなPostgreSQLグループ
これにより、選択した列の一意の値ごとに、他のクエリ条件と一致する1つのレコードを取得できます。
MyModel.where(:some_col => value).select("DISTINCT ON (unique_col) *")
行内の他のすべての列値を取得できるため、DISTINCT ONを選択します。 DISTINCTのみでは、その特定の列の値のみが返されます。
自分でエラーを頻繁に受け取った後、Rails(私はRails 4)を使用しています)がグループ化クエリの最後に 'order by id'を自動的に追加することに気付きましたこれにより、上記のエラーが発生することがよくあります。したがって、Railsクエリの最後に独自の.order(:group_by_column)を追加してください。したがって、次のようになります。
@problems = Problem.select('problems.username, sum(problems.weight) as weight_sum').group('problems.username').order('problems.username')