Postgres is different from MySQL and SQLite in how it treats GROUP BY
. In essence, it's very strict. Let's say you have.
id name
1 foo
2 bar
2 baz
Then you're doing GROUP BY id
. MySQL assumes that you just want to drop all but the first name. So it will produce.
id name
1 foo
2 bar
However, Postgres will not be guessing the grouping method in this case. It needs a specific instruction of how you want to group other columns. It provides what's called aggregate functions for that purpose, and in this case you're looking for a function that takes a first of a bunch. I couldn't find a function that does that, but perhaps min()
or max()
could serve as one. In that case you need to use :select => 'min(comments.id), min(comments.some_other_column)'
, and this you should do for every column except user_id. Then you can use :group => 'user_id' without problems.
Btw, min()
and max()
accept strings, not just numbers, so they should work for any column. If you want to really take the first of a bunch, then google for "postgres aggregate first" to find some implementations, or use postgres arrays. Although these would break compatibility with mysql and sqlite.
Update
On the other hand if fetching recent comments isn't too expensive, let ruby handle the unique users part.
unique_comments = []
Comment.recent.each do |comment|
unless unique_comments.find{|c| c.user_id == comment.user_id}
unique_comments << comment
end
break if unique_comments.size > 2
end
Now you have at most 3 comments from distinct users.