4

I know PostgreSQL, unlike MySQL, requires to list all selected fields in the group by clause when using aggregate functions, e.g.

Transaction.select('sum(amount), category_id').group('category_id')

Fair enough. But when I try to eager load an association, e.g.

Transaction.select('sum(amount), categories.name').includes(:category).group('categories.name')

it doesn't work because you haven't included all fields of both models in the group by clause.

Is there a way to avoid having to list all fields of the models, or should I consider accepting the N+1 queries? (I don't think listing 30 fields makes sense when I only need 2...)

Chris Travers
  • 25,424
  • 6
  • 65
  • 182
Pierre
  • 8,368
  • 4
  • 34
  • 50
  • 1
    Every DBMS requires to list all fields in the group by, MySQL is the exception. And it's responsible for many bugs because of this behaviour. – Frank Heikens Aug 30 '11 at 18:26

2 Answers2

4

As of new versions of PostgreSQL (9.1+ if I recall correctly) you can group by the primary keys of the tables only. Previous versions (and most RDBMSs as well) require that you provide all columns. The key-only exception works because we know all attributes are functionally dependent on the key so if the key changes, the other attributes will be distinct anyway.

MySQL is an exception, as Frank pointed out in the comments above. This is responsible for many non-deterministic aspects of that database in cases like this. Non-deterministic is generally bad and to be avoided.

Chris Travers
  • 25,424
  • 6
  • 65
  • 182
0

Another work around: one could list all those keys with:

Model.first.attributes.keys.map{|a| "table_name.#{a}".to_sym}
Julien Lamarche
  • 931
  • 1
  • 12
  • 29