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

前端 未结 3 482
刺人心
刺人心 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: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).

提交回复
热议问题