I want to do several aggregate functions at once, eg to get the max and min id's grouped by status:
Model.maximum(:id).minimum(:id).group(:status)
This doesnt work (at least with Rails 3.1.1) - you get an error on the minimum call, saying its not defined on Fixnum.
NoMethodError: undefined method `minimum' for 22377:Fixnum
I could do raw sql for it - but just wondering if there is a higher level/Rails option...
Thanks, Chris
SQL does not permit the application of an aggregate function to another aggregate function or a subquery, so the only ways I can think to do this are by using a temporary table or by iterating through the result set and manually calculating the values.
The only column names that can be displayed, along with aggregate functions, must be listed in the GROUP BY clause.
The n+1 query problem is one of the most common scalability bottlenecks. It involves fetching a list of resources from a database that includes other associated resources within them. This means that we might have to query for the associated resources separately.
Active Record uses naming conventions for the columns in database tables, depending on the purpose of these columns. Foreign keys - These fields should be named following the pattern singularized_table_name_id (e.g., item_id , order_id ).
I've had a similar issue which I solved using group with pluck in Rails 4. E.g.
Model.group(:status).pluck('min(id)','max(id)')
Also works with having, order etc and with computed columns.
Model.group('CAST(created_at AS Date), EXTRACT(HOUR FROM created_at), floor(EXTRACT(MINUTE FROM created_at)/15) * 15')
.having('count(id) > 10')
.order('min(created_at)')
.pluck('count(id)')
Cheers
I believe @topek is right that you can't chain the calculation functions like this. I think you'll have to use SQL in a select
predicate, e.g.:
Model.select('MAX(id) AS `maximum`, MIN(id) AS `minimum`').group(:status)
I just tested this in a project of my own and it appears to work as expected.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With