Rails / Postgres: “must appear in the GROUP BY clause or be used in an aggregate function”

前端 未结 3 450
刺人心
刺人心 2021-01-19 05:41

I\'m using this method:

  def self.lines_price_report(n)
    Income.group(\'date(filled_at)\').having(\"date(filled_at) > ?\", Date.today - n).sum(:lines_         


        
相关标签:
3条回答
  • 2021-01-19 06:22

    When you want to use Group By on PostgreSQL, The select option should be required on the group by.

    Income.select('filled_at').group('date(filled_at)').having("date(filled_at) > ?", Date.today - n).sum(:lines_price)
    
    0 讨论(0)
  • 2021-01-19 06:30

    I guess this is because you use date(filled_at) in GROUP BY but just filled at in ORDER. As I guess order is taken from default scope you need to overwrite it by reorder. I would suggest:

    Income.sum(:lines_price).
        group('date(filled_at)').
        having("date(filled_at) > ?", Date.today - n).
        reorder("date(filled_at) ASC")
    
    0 讨论(0)
  • 2021-01-19 06:34

    Your mistake was to use filled_at in order by probably in default scope.

    You can fix it using unscoped to eliminate default scopes:

    Income.unscoped
     .group('date(filled_at)')
     .having("date(filled_at) > ?", Date.today - n)
     .sum(:lines_price)
    

    or

    Income.unscoped
       .group('date(filled_at)')
       .having("date(filled_at) > ?", Date.today - n)
       .sum(:lines_price)
       .order('date(filled_at) ASC')
    

    but I think that better will be to use where instead of having

    Income.unscoped
      .where("date(filled_at) > TIMESTAMP ?", Date.today - n)
      .group('date(filled_at)')
      .sum(:lines_price)
      .order('date(filled_at) ASC')
    

    SQLFiddle

    You have to be careful about using TIMESTAMP because 2012-12-04 will become 2012-12-04 00:00:00 so if you don't want this day in result use Date.today - (n - 1)

    If you create index on filled_at column

     create index incomes_filled_at on incomes(filled_at);
    

    migration:

     add_index :incomes, :filled_at
    

    and you have a lot of data in this table index will be used in filtering. So query should be much faster.

    So just write both and test which is faster (you have to create index on filled_at if you don't have one).

    0 讨论(0)
提交回复
热议问题