コントローラに、最高の平均レビュー評価でアルバムをランク付けするコードがあります(このソリューションのコードを使用 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には少し慣れていないため、開発環境と運用環境の両方で機能するようにコードをリファクタリングするのに苦労しています。
reviews.id
(ワイルドカード*
で暗黙的に選択)をGROUP BY
句に追加したり、avg()
のような集約関数を適用したりせずに選択することはできません。解決策は、次のいずれかを実行することです。
*
を削除しますreviews.id
を追加しますreviews.id
を明示的に選択し、集約関数を適用します(例:sum(reviews.id)
)*
をテーブル固有のワイルドカードalbums.*
に置き換えますただし、シナリオでは2番目と3番目のオプションはあまり意味がありません。コメントに基づいて、オプション4を追加しました。
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」を使用)
この種の問題に対して私が見つけた唯一の本当に受け入れられる解決策は、次のコードでした。
@albums = Album.joins(:reviews).select("*, avg(reviews.rating) as average_rating").group_by(&:id).order("average_rating DESC")
私はそれが誰かを助けることを願っています。