PGError:错误:对象的AR查询及其has_many对象的WHERE子句中不允许聚合

时间:2011-12-30 22:01:28

标签: ruby-on-rails ruby-on-rails-3 postgresql activerecord count

在has_many关联上运行以下查询。建议has_many Approvals。

我正在运行,rails 3和PostgreSQL:

Recommendation.joins(:approvals).where('approvals.count = ?
                      AND recommendations.user_id = ?', 1, current_user.id)

这会返回以下错误:https://gist.github.com/1541569

2 个答案:

答案 0 :(得分:5)

错误消息告诉您:

  

WHERE子句

中不允许聚合

count()是一个聚合函数。请使用HAVING clause
查询可能如下所示:

SELECT r.*
FROM   recommendations r
JOIN   approvals       a ON a.recommendation_id = r.id
WHERE  r.user_id = $current_user_id
GROUP  BY r.id
HAVING count(a.recommendation_id) = 1

使用PostgreSQL 9.1或更高版本,GROUP BY表的主键就足够了(假设recommendations.id 是PK)。在9.1之前的Postgres版本中,您必须包含SELECT列表中未汇总在GROUP BY列表中的所有列。 recommendations.*列表中的SELECT,即表格的每一列。

我引用release notes of PostgreSQL 9.1

  

主要时,在查询目标列表中允许非GROUP BY列   key在GROUP BY子句中指定(Peter Eisentraut)

使用子选择

更简单

无论哪种方式,这都更简单,更快,做同样的事情:

SELECT *
FROM   recommendations r
WHERE  user_id = $current_user_id
AND   (SELECT count(*)
       FROM   approvals
       WHERE  recommendation_id = r.id) = 1;

避免将行与JOIN先验相乘,然后您不必将它们聚合回来。

答案 1 :(得分:1)

看起来你有一个名为count的列,而PostgreSQL正在将该列名解释为count聚合函数。您的SQL最终会像这样:

SELECT "recommendations".*
FROM "recommendations"
INNER JOIN "approvals" ON "approvals"."recommendation_id" = "recommendations"."id"
WHERE (approvals.count = 1 AND recommendations.user_id = 1)

错误消息明确指向approvals.count

LINE 1: ...ecommendation_id" = "recommendations"."id" WHERE (approvals....
                                                             ^

我无法在PostgreSQL(9.0)中重现该错误,但您可能正在使用其他版本。请尝试在where

中双引用该列名称
Recommendation.joins(:approvals).where('approvals."count" = ? AND recommendations.user_id = ?', 1, current_user.id)

如果对此进行排序,我建议您将approvals.count列重命名为其他内容,以便您不必再担心它了。