wake-up-neo.com

GroupingError: ERROR: Spalte muss in der GROUP BY-Klausel erscheinen oder in einer Aggregatfunktion verwendet werden

Ich habe in meinem Controller einen Code, der Alben nach der höchsten durchschnittlichen Bewertungsrangfolge bewertet (verwendeter Code aus dieser Lösung Wie werden die am höchsten bewerteten Alben über eine has_many-Bewertungsbeziehung angezeigt ): 

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

Dieser Code funktioniert in meiner Entwicklungsumgebung (sqlite3) einwandfrei. Als ich den Code zu heroku und postgresql puschte, bekam ich jedoch diesen Fehler: 

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

Mir ist klar, dass dies ein ziemlich häufiges Problem ist. Ich bin ein wenig unerfahren mit SQL, daher habe ich Probleme, den Code zu überarbeiten, damit er sowohl in meiner Entwicklungs- als auch in der Produktionsumgebung funktioniert. 

26
Reuben

Sie dürfen reviews.id nicht auswählen (implizit durch den Platzhalter * ausgewählt), ohne es der GROUP BY-Klausel hinzuzufügen oder eine Aggregatfunktion wie avg() anzuwenden. Die Lösung besteht darin, eine der folgenden Aktionen auszuführen:

  1. Entfernen Sie den Platzhalter * aus Ihrer Auswahl
  2. Fügen Sie der Gruppenklausel das Feld reviews.id hinzu
  3. Wählen Sie explizit reviews.id aus und wenden Sie eine Aggregatfunktion darauf an (z. B. sum(reviews.id)). 
  4. Ersetzen Sie den Platzhalter * durch den tabellenspezifischen Platzhalter albums.*

Die zweite und dritte Option machen in Ihrem Szenario jedoch nicht viel Sinn. Basierend auf Ihrem Kommentar habe ich Option vier hinzugefügt.

28
slash

Ich möchte diesen Code nur mit aktivem Datensatz (sinatra) auf Ruby freigeben.

Ich musste "group by" zu einer "order by" -Funktion hinzufügen, also Codezeile ...

von:

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

zu:

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

und es hat perfekt funktioniert. Denken Sie daran, dass das ID-Feld in diesem Fall "Port.id" zur Gruppenklausel hinzugefügt werden muss. Andernfalls wird dieser Fehler ausgegeben. Wie @slash erwähnt, können Sie dies nicht mit speziellen Funktionen erreichen (implizit durch den Platzhalter auswählen) * oder in meinem Fall "all")

1
d1jhoni1b

Die einzige wirklich akzeptable Lösung, die ich für diese Art von Problem gefunden habe, war mit diesem Code:

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

Ich hoffe es hilft jemandem.

0
Weengs