【问题标题】:GroupingError: ERROR: column must appear in the GROUP BY clause or be used in an aggregate functionGroupingError:错误:列必须出现在 GROUP BY 子句中或在聚合函数中使用
【发布时间】:2014-01-23 09:57:21
【问题描述】:

我的控制器中有代码按最高平均评论评分对专辑进行排名(使用此解决方案中的代码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 有点缺乏经验,所以我在重构代码时遇到了麻烦,以便它可以在我的开发和生产环境中工作。

【问题讨论】:

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


    【解决方案1】:

    如果不将reviews.id 添加到GROUP BY 子句或应用avg() 之类的聚合函数,则不允许选择reviews.id(通过通配符* 隐式选择)。解决方案是执行以下操作之一:

    1. 从您的选择中删除通配符 *
    2. 将字段reviews.id 添加到您的组子句中
    3. 明确选择reviews.id 并对其应用聚合函数(例如sum(reviews.id)
    4. 将通配符* 替换为特定于表的通配符albums.*

    第二个和第三个选项在您的场景中没有多大意义。 根据您的评论,我添加了选项四。

    【讨论】:

    • 知道了,所以我不应该使用通配符*,而是应该像这样显式列出 select 子句中的每个列名? @albums = Album.joins(:reviews).select("reviews.rating, albums.id, albums.name, albums.artist, albums.picture, avg(reviews.rating) as average_rating").group("albums.id").order("average_rating DESC")
    • 你可以试试@albums = Album.joins(:reviews).select("albums.*, avg(reviews.rating) as average_rating").group("albums.id").order("average_rating DESC")
    • 我不太确定您实际要选择哪些字段。但在您的评论中,您尝试选择reviews.ratingavg(reviews.rating)。因此,在一个结果行中,您试图一次获得当前行评级和平均评级?您可以编辑您的问题并添加评论和专辑的表格结构,以及您希望收到的字段。
    • 您之前的评论成功了。对于@albums,我试图让我的专辑模型中的所有字段按照专辑在我的视图中显示的高度排序。我的最后一条评论是我未能理解您的第一个建议(从选择中删除通配符)的含义。
    【解决方案2】:

    只想使用活动记录 (sinatra) 在 ruby​​ 上分享此代码

    我必须在“order by”函数中添加“group 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 字段“Port.id”必须添加到组子句中,否则会引发此错误,并且正如@slash 所提到的,您无法使用特殊功能来实现这一点(隐式选择通过通配符 * 或在我的情况下使用“all”)

    【讨论】:

      猜你喜欢
      • 2015-06-22
      • 1970-01-01
      • 2017-02-28
      • 1970-01-01
      • 2014-12-26
      • 2020-06-11
      • 2020-11-04
      • 2016-09-16
      相关资源
      最近更新 更多