GroupingError:ERROR:列必须出现在GROUP BY子句中或用于聚合函数

时间:2014-01-06 03:25:36

标签: ruby-on-rails postgresql activerecord sqlite ruby-on-rails-4

我的控制器中的代码是按最高平均评价评分(使用此解决方案中的代码How to display highest rated albums through a has_many reviews relationship)对相册进行排名:

@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有点缺乏经验,因此我无法重构代码,因此它可以在我的开发和生产环境中工作。

3 个答案:

答案 0 :(得分:29)

您不能选择reviews.id(通过通配符*隐式选择)而不将其添加到GROUP BY子句或应用avg()等聚合函数。解决方案是执行以下操作之一:

  1. 从您的选择
  2. 中删除通配符*
  3. 将字段reviews.id添加到您的组子句
  4. 明确选择reviews.id并对其应用聚合函数(例如sum(reviews.id)
  5. 将通配符*替换为特定于表的通配符albums.*
  6. 第二个和第三个选项在你的场景中没有多大意义。 根据您的评论,我添加了选项四。

答案 1 :(得分:1)

只想使用活动记录(sinatra)

在ruby上分享此代码

我不得不将“group by”添加到“order by”函数中,所以代码行......

从:

hover

为:

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

并且它工作得很完美,只记得ID字段在这种情况下“Port.id”必须添加到group子句中否则会引发此错误,并且正如@slash所提到的那样你无法用特殊函数实现这一点(隐式选择)通过通配符*或在我的情况下使用“所有”)

答案 2 :(得分:0)

我发现这种问题的唯一真正可接受的解决方案是使用此代码:

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

我希望它有所帮助。