PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Rails / Postgres :"doit apparaître dans la clause GROUP BY ou être utilisé dans une fonction d'agrégation"

Votre erreur a été d'utiliser filled_at dans l'ordre probablement dans la portée par défaut.

Vous pouvez résoudre ce problème en utilisant unscoped pour éliminer les champs d'application par défaut :

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

ou

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

mais je pense qu'il vaudrait mieux utiliser where au lieu d'avoir

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

SQLFiddle

Vous devez faire attention à l'utilisation de TIMESTAMP car 2012-12-04 deviendra 2012-12-04 00:00:00 donc si vous ne voulez pas ce jour dans le résultat, utilisez Date.today - (n - 1)

Si vous créez un index sur la colonne filled_at

 create index incomes_filled_at on incomes(filled_at);

migration :

 add_index :incomes, :filled_at

et vous avez beaucoup de données dans cet index de table qui seront utilisées pour le filtrage. La requête devrait donc être beaucoup plus rapide.

Donc, écrivez simplement les deux et testez ce qui est le plus rapide (vous devez créer un index sur filled_at si vous n'en avez pas).