web-dev-qa-db-ja.com

GroupingError:エラー:列はGROUP BY句に表示されるか、集計関数で使用される必要があります

コントローラに、最高の平均レビュー評価でアルバムをランク付けするコードがあります(このソリューションのコードを使用 has_manyのレビュー関係で最高評価のアルバムを表示する方法 ):

@albums = Album.joins(:reviews).select("*, avg(reviews.rating) as average_rating").group("albums.id").order("average_rating DESC")

このコードは私の開発環境(sqlite3)で完全に機能しますが、コードをherokuとpostgresqlにプッシュすると、このエラーが発生しました。

PG::GroupingError: ERROR:  column "reviews.id" must appear in the GROUP BY clause or be used in an aggregate function

これはかなり一般的な問題であり、SQLには少し慣れていないため、開発環境と運用環境の両方で機能するようにコードをリファクタリングするのに苦労しています。

29
Reuben

reviews.id(ワイルドカード*で暗黙的に選択)をGROUP BY句に追加したり、avg()のような集約関数を適用したりせずに選択することはできません。解決策は、次のいずれかを実行することです。

  1. 選択からワイルドカード*を削除します
  2. グループ句にフィールドreviews.idを追加します
  3. reviews.idを明示的に選択し、集約関数を適用します(例:sum(reviews.id)
  4. ワイルドカード*をテーブル固有のワイルドカードalbums.*に置き換えます

ただし、シナリオでは2番目と3番目のオプションはあまり意味がありません。コメントに基づいて、オプション4を追加しました。

31
slash

Rubyでアクティブなレコードを使用してこのコードを共有したい(sinatra)

「group by」を「order by」関数に追加する必要があったため、コードの行...

から:

@models = Port.all.order('number asc')

に:

@models = Port.select(:id, :device_id, :number, :value, :sensor, :UOM).all.order('number asc').group(:id,:sensor,:UOM)

そしてそれは完璧に機能しました。この場合、IDフィールドをグループ句に追加する必要があることを覚えておいてください*または私の場合は「all」を使用)

1
d1jhoni1b

この種の問題に対して私が見つけた唯一の本当に受け入れられる解決策は、次のコードでした。

@albums = Album.joins(:reviews).select("*, avg(reviews.rating) as average_rating").group_by(&:id).order("average_rating DESC")

私はそれが誰かを助けることを願っています。

0
MoskitoHero