【问题标题】:Group By Year, Month & then Count in ActiveRecord 3按年、月分组,然后在 ActiveRecord 3 中计数
【发布时间】:2011-12-12 04:24:13
【问题描述】:

我正在尝试统计一年和一个月内创建的所有用户,但以下内容似乎没有按预期工作。

User.group("YEAR(created_AT), MONTH(created_at)").
     count("DISTINCT(id), YEAR(created_at), MONTH(created_at)")

我正在寻找类似的东西

{2011 => {1 => 222, 2 => 333, 4 => 444, 5 => 667 ... }}

但我得到了

{1 => 222, 2 => 333, 4 => 444, 5 => 667 ... }

我是否遗漏了什么,或者 ActiveRecord 不能在一个查询中给我这个结果?

【问题讨论】:

    标签: sql ruby-on-rails ruby activerecord


    【解决方案1】:

    count 方法不像你想象的那样工作。你最终会这样做:

    select count(distinct(id), year(created_at), month(created_at))
    from users
    group by year(created_at), month(created_at)
    

    那个 SELECT 子句非常狡猾,但 MySQL 会以它通常草率的方式让它通过。我想你想要这个查询:

    select count(distinct(id)), year(created_at), month(created_at)
    from users
    group by year(created_at), month(created_at)
    

    我可能会像这样直接去select_all

    a = User.connection.select_all(%q{
        select count(distinct(id)) as c, year(created_at) as y, month(created_at) as m
        from users
        group by y, m
    })
    

    或者你可以这样做:

    a = User.connection.select_all(
        User.select('count(distinct(id)) as c, year(created_at) as y, month(created_at) as m').
             group('y, m')
    )
    

    这些会给你一个数组,a,带有cym这样的键:

    a = [
        { 'c' => '23', 'y' => '2010', 'm' => '11' },
        { 'c' => '1',  'y' => '2011', 'm' =>  '1' },
        { 'c' => '5',  'y' => '2011', 'm' =>  '3' },
        { 'c' => '2',  'y' => '2011', 'm' =>  '4' },
        { 'c' => '11', 'y' => '2011', 'm' =>  '8' }
    ]
    

    然后,您只需进行一些数据整理即可完成工作:

    h = a.group_by { |x| x['y'] }.each_with_object({}) do |(y,v), h|
        h[y.to_i] = Hash[v.map { |e| [e['m'].to_i, e['c'].to_i] }]
    end
    # {2010 => {11 => 23}, 2011 => {1 => 1, 3 => 5, 4 => 2, 8 => 11}} 
    

    【讨论】:

      猜你喜欢
      • 2017-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-22
      • 1970-01-01
      • 2015-12-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多