PGError: ERROR: aggregates not allowed in WHERE clause on a AR query of an object and its has_many objects

后端 未结 2 2157
深忆病人
深忆病人 2020-12-02 02:39

Running the following query on a has_many association. Recommendations has_many Approvals.

I am running, rails 3 and PostgreSQL:

Recommendation.join         


        
相关标签:
2条回答
  • 2020-12-02 03:17

    The error message tells you:

    aggregates not allowed in WHERE clause

    count() is an aggregate function. Use the HAVING clause for that.
    The query could look like this:

    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
    

    With PostgreSQL 9.1 or later it is enough to GROUP BY the primary key of a table (presuming recommendations.id is the PK). In Postgres versions before 9.1 you had to include all columns of the SELECT list that are not aggregated in the GROUP BY list. With recommendations.* in the SELECT list, that would be every single column of the table.

    I quote the release notes of PostgreSQL 9.1:

    Allow non-GROUP BY columns in the query target list when the primary key is specified in the GROUP BY clause (Peter Eisentraut)

    Simpler with a sub-select

    Either way, this is simpler and faster, doing the same:

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

    Avoid multiplying rows with a JOIN a priori, then you don't have to aggregate them back.

    0 讨论(0)
  • 2020-12-02 03:28

    Looks like you have a column named count and PostgreSQL is interpreting that column name as the count aggregate function. Your SQL ends up like this:

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

    The error message specifically points at the approvals.count:

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

    I can't reproduce that error in my PostgreSQL (9.0) but maybe you're using a different version. Try double quoting that column name in your where:

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

    If that sorts things out then I'd recommend renaming your approvals.count column to something else so that you don't have to worry about it anymore.

    0 讨论(0)
提交回复
热议问题