I think there is a misunderstanding going on here.

relation.count will always perform a count on database, it won't load every
row in our ruby process:

(main) normal> u = User.group(:profile_id); u.count
   (0.4ms)  SELECT COUNT(*) AS count_all, profile_id AS profile_id FROM
"users"  GROUP BY profile_id
=> {1=>4, 2=>1}
(main) normal> u.count
   (0.4ms)  SELECT COUNT(*) AS count_all, profile_id AS profile_id FROM
"users"  GROUP BY profile_id
=> {1=>4, 2=>1}
(main) normal> u.count.values.sum
   (0.3ms)  SELECT COUNT(*) AS count_all, profile_id AS profile_id FROM
"users"  GROUP BY profile_id
=> 5


Performing u.count.values.sum will also perform a grouped count and just
sum the quantity of rows for every key.

On Mon, Sep 15, 2014 at 8:57 AM, G. Sobrinho <gabriel.sobri...@gmail.com>
wrote:

> That's the point, relation.count will *always* perform a COUNT on database.
>
> On Mon, Sep 15, 2014 at 8:50 AM, Will Bryant <will.bry...@gmail.com>
> wrote:
>
>> Yes, but it will have to *load* all the rows from the database into ruby.
>>  If we have a table with a few million of rows, which is pretty small for a
>> real app, and we're doing a join and a group to get the count of some
>> associated record, then calling .values.sum would load all those millions
>> of rows, and then add up the values.
>>
>> Returning the millions of rows (even if it was just the IDs and counts)
>> is many orders of magnitude slower than getting the database to tell us how
>> many rows would be in the rowset, and it's going to use a lot of memory too.
>>
>> Yes, if your app only has thousands of rows, then it won't matter.  But
>> this is not a good argument for a database library to be inefficient.
>>
>> The point is that count should always return a count of the results in a
>> relation, irrespective of what is involved in the relation.  That's the
>> point of relational algebra; you can combine two operations and you get the
>> logical composite.
>>
>> Returning the count of each grouping is a logically separate thing to do,
>> and it should have a separate API call.
>>
>>
>> On 15/09/2014, at 23:36 , G. Sobrinho <gabriel.sobri...@gmail.com> wrote:
>>
>> I'm not sure if you get what .values.sum would do:
>>
>> c = User.group(:role).count
>> => {:normal=>3, :admin=>4}
>>
>> c.values.sum
>> => 7
>>
>>
>> Even a hash with thousands of keys/values would sum its values very fast.
>>
>>
>> And I don't get what you mean with "is actually changing what would be
>> counted".
>>
>> Considering c = User.group(:role).count, c.values.sum would return the
>> exactly number of records that would be returned and c.keys.sum would
>> return exactly number of group param that would be returned, no?
>>
>> On Sun, Sep 14, 2014 at 2:20 AM, Will Bryant <will.bry...@gmail.com>
>> wrote:
>>
>>> Calling .values.sum might have to load a LOT of (id, count) rows so it
>>> isn't a very scalable solution.
>>>
>>> Calling regroup or something is actually changing what would be counted
>>> - the group can affect the count, especially if you use HAVING clauses.
>>>
>>> There's nothing wrong with having the grouped count functionality, but
>>> it's messing up the #count API IMHO.
>>>
>>>
>>> On 13/09/2014, at 03:40 , Gabriel Sobrinho <gabriel.sobri...@gmail.com>
>>> wrote:
>>>
>>> I'm against to count and size works equally since I would want to know
>>> how many grouped records do I have (i.e.: how many roles do I have on
>>> determining relation).
>>>
>>> I think that count and size is working as both should.
>>>
>>>
>>> Although, if you want to count all records of a grouped relation, you
>>> have to remove the group or just sum the counts:
>>>
>>> User.count
>>>
>>>
>>> or:
>>>
>>>
>>>
>>> User.group(:role).count.values.sum
>>>
>>>
>>> Not elegant but if you can't remove the group for that count, you have
>>> to do that.
>>>
>>>
>>> One possible option would rails have something like regroup(false) as
>>> reorder(false), but again I think that just adding the values is more
>>> easier for everyone :)
>>>
>>> On Thursday, September 11, 2014 11:54:14 PM UTC-3, Shinohara Teruki
>>> wrote:
>>>>
>>>> >> size in this case is an pretty much an "alias" for count, thus it's
>>>> gonna work the same way as count when grouping.
>>>>
>>>> I think that current #size don't behave like an alias for #count.
>>>>
>>>> g = User.group(:role); g.load; g.count
>>>> => {:normal=>3, :admin=>4}
>>>>
>>>> g = User.group(:role); g.load; g.size
>>>> => 2
>>>>
>>>> When I call #load before #count or #size, a return value of #count
>>>> don't equals to a return value of #size.
>>>>
>>>>
>>>> >> Is there any particular reason to know how many records returned if
>>>> you are grouping?
>>>>
>>>> I expect #count and #size to return same value.
>>>> It is not the case that I want to know how many records the grouping
>>>> query returns.
>>>>
>>>> My ideal implementation:
>>>>
>>>> g = User.group(:role); g.load; g.count
>>>> => {:normal=>3, :admin=>4}
>>>>
>>>> g = User.group(:role); g.load; g.size
>>>> =>{:normal=>3, :admin=>4}
>>>>
>>>> or
>>>>
>>>> g = User.group(:role); g.load; g.count
>>>> => 2
>>>>
>>>> g = User.group(:role); g.load; g.size
>>>> =>2
>>>>
>>>> What do you think?
>>>>
>>>> Thank you
>>>>
>>>>
>>>> 2014年9月12日金曜日 8時21分39秒 UTC+9 Carlos Antonio da Silva:
>>>>>
>>>>> size in this case is an pretty much an "alias" for count, thus it's
>>>>> gonna work the same way as count when grouping.
>>>>>
>>>>> Is there any particular reason to know how many records returned if
>>>>> you are grouping?
>>>>>
>>>>> On Wed, Sep 10, 2014 at 11:16 AM, Shinohara Teruki <ts....@gmail.com>
>>>>> wrote:
>>>>>
>>>>>> ActiveRecord::Relation.size returns a Hash when I use a group method.
>>>>>> I think that a size method is expected to return integer typically.
>>>>>>
>>>>>> I propose this  implementation:
>>>>>>
>>>>>>     def size
>>>>>>       if loaded?
>>>>>>         @records.length
>>>>>>       else
>>>>>>         count_value = count(:all)
>>>>>>         count_value.is_a?(Hash) ? count_value.length : count_value
>>>>>>       end
>>>>>>     end
>>>>>>
>>>>>> This is a current implementation:
>>>>>>
>>>>>> # https://github.com/rails/rails/blob/master/activerecord/lib/active_
>>>>>> record/relation.rb
>>>>>>     # Returns size of the records.
>>>>>>     def size
>>>>>>       loaded? ? @records.length : count(:all)
>>>>>>     end
>>>>>>
>>>>>>
>>>>>> A count method is implemented on calculations.rb.
>>>>>> https://github.com/rails/rails/blob/master/activerecord/lib/active_
>>>>>> record/relation/calculations.rb
>>>>>>
>>>>>>
>>>>>> What do you think?
>>>>>>
>>>>>> Thank you
>>>>>>
>>>>>> --
>>>>>> You received this message because you are subscribed to the Google
>>>>>> Groups "Ruby on Rails: Core" group.
>>>>>> To unsubscribe from this group and stop receiving emails from it,
>>>>>> send an email to rubyonrails-co...@googlegroups.com.
>>>>>> To post to this group, send email to rubyonra...@googlegroups.com.
>>>>>> Visit this group at http://groups.google.com/group/rubyonrails-core.
>>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>>
>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> At.
>>>>> Carlos Antonio
>>>>>
>>>>
>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "Ruby on Rails: Core" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to rubyonrails-core+unsubscr...@googlegroups.com.
>>> To post to this group, send email to rubyonrails-core@googlegroups.com.
>>> Visit this group at http://groups.google.com/group/rubyonrails-core.
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>>
>>>
>>> --
>>> You received this message because you are subscribed to a topic in the
>>> Google Groups "Ruby on Rails: Core" group.
>>> To unsubscribe from this topic, visit
>>> https://groups.google.com/d/topic/rubyonrails-core/2BELBVaNEeA/unsubscribe
>>> .
>>> To unsubscribe from this group and all its topics, send an email to
>>> rubyonrails-core+unsubscr...@googlegroups.com.
>>> To post to this group, send email to rubyonrails-core@googlegroups.com.
>>> Visit this group at http://groups.google.com/group/rubyonrails-core.
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>
>>
>>
>> --
>> Cheers,
>>
>> Gabriel Sobrinho
>> http://gabrielsobrinho.com/
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "Ruby on Rails: Core" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to rubyonrails-core+unsubscr...@googlegroups.com.
>> To post to this group, send email to rubyonrails-core@googlegroups.com.
>> Visit this group at http://groups.google.com/group/rubyonrails-core.
>> For more options, visit https://groups.google.com/d/optout.
>>
>>
>>  --
>> You received this message because you are subscribed to a topic in the
>> Google Groups "Ruby on Rails: Core" group.
>> To unsubscribe from this topic, visit
>> https://groups.google.com/d/topic/rubyonrails-core/2BELBVaNEeA/unsubscribe
>> .
>> To unsubscribe from this group and all its topics, send an email to
>> rubyonrails-core+unsubscr...@googlegroups.com.
>> To post to this group, send email to rubyonrails-core@googlegroups.com.
>> Visit this group at http://groups.google.com/group/rubyonrails-core.
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>
>
> --
> Cheers,
>
> Gabriel Sobrinho
> http://gabrielsobrinho.com/
>



-- 
Cheers,

Gabriel Sobrinho
http://gabrielsobrinho.com/

-- 
You received this message because you are subscribed to the Google Groups "Ruby 
on Rails: Core" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to rubyonrails-core+unsubscr...@googlegroups.com.
To post to this group, send email to rubyonrails-core@googlegroups.com.
Visit this group at http://groups.google.com/group/rubyonrails-core.
For more options, visit https://groups.google.com/d/optout.

Reply via email to