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

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

我正在运行rails 3和PostgreSQL:

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

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

错误消息告诉您:

WHERE子句中不允许聚合

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

 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表的主键就足够了(假设suggest.id PK)。 在9.1之前的Postgres版本中,您必须包括SELECT列表中未在GROUP BY列表中聚合的所有列。 使用SELECT列表中的recommendations.* ,这将是表的每一列。

我引用了PostgreSQL 9.1的发行说明 :

GROUP BY子句中指定主键时,允许查询目标列表中的非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先验相乘,然后您不必将它们聚合回来。

看起来你有一个名为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列重命名为其他内容,以便您不必再担心它了。