PG :: GROUP BY子句中的错误
我想不出更好的方法来重构下面的代码(看到这个问题 ),虽然我知道它非常难看。 但是,它会抛出一个Postgres错误(不是SQLite):
ActiveRecord::StatementInvalid: PG::Error: ERROR: column "articles.id" must appear in the GROUP BY clause or be used in an aggregate function
查询本身是:
SELECT "articles".* FROM "articles" WHERE "articles"."user_id" = 1 GROUP BY publication
它来自以下视图代码:
=@user.articles.group(:publication).map do |p| =p.publication =@user.articles.where("publication = ?", p.publication).sum(:twitter_count) =@user.articles.where("publication = ?", p.publication).sum(:facebook_count) =@user.articles.where("publication = ?", p.publication).sum(:linkedin_count)
在SQLite中,这给出了输出(例如)NYT 12 18 14 BBC 45 46 47 CNN 75 54 78,这正是我所需要的。
如何改进代码以消除此错误?
克雷格的回答很好地解释了这个问题。 Active Record将默认select *
,但您可以轻松覆盖它:
@user.articles.select("publication, sum(twitter_count) as twitter_count").group(:publication).each do |row| p row.publication # "BBC" p row.twitter_count # 45 end
使用GROUP BY
,不能SELECT
既不是GROUP BY
一部分也不能在聚合函数中使用的字段。 这是由SQL标准指定的,尽管有些数据库选择执行此类查询。 由于没有一种正确的方法来执行这样的查询,因此他们倾向于选择他们找到的第一行并返回该行,因此结果将无法预测地变化。
看起来你想说:
“对于每个出版物,请获取该出版物的twitter,facebook和linkedin计数的总和”。
如果是这样,你可以写:
SELECT publication, sum(twitter_count) AS twitter_sum, sum(linkedin_count) AS linkedin_sum, sum(facebook_count) AS facebook_sum FROM "articles" WHERE "articles"."user_id" = 1 GROUP BY publication;
将其转换为ActiveRecord / Rails ……由我决定,我不使用它。 看起来它几乎是你试图编写的,但ActiveRecord似乎正在破坏它,可能试图在本地执行总和。