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

Meilleur moyen dans MySQL ou Rails d'obtenir AVG par jour dans une plage de dates spécifique

Y a-t-il une raison (autre que la date déjà mentionnée) pour laquelle vous n'utiliseriez pas les capacités de fonction de groupe intégrées dans ActiveRecord ? Vous semblez vous préoccuper du "post-traitement", ce qui, à mon avis, n'est pas vraiment un sujet de préoccupation.

Vous êtes dans Rails, vous devriez donc probablement d'abord rechercher une solution Rails[1]. Ma première pensée serait de faire quelque chose comme

Product.average(:sales_price, :group => "DATE(created_at)", :conditions => ["merchant_id=?", 1])

lequel ActiveRecord est devenu à peu près le SQL que vous avez décrit. En supposant qu'il y ait un has_many déclaré association entre le marchand et le produit, alors vous feriez probablement mieux de l'utiliser, donc quelque chose comme :

ave_prices = Merchant.find(1).products.average(:sales_price, :group => "DATE(created_at)")

(J'espère que votre description du modèle en tant que "products_sold" est une sorte d'erreur de transcription, d'ailleurs - sinon, vous êtes un peu hors-message avec votre nom de classe !)

Après tout cela, vous êtes de retour là où vous avez commencé, mais vous y êtes arrivé d'une manière Rails plus conventionnelle (et Rails valorise vraiment les conventions !). Maintenant, nous devons combler les lacunes.

Je suppose que vous connaissez votre plage de dates, disons qu'elle est définie comme toutes les dates de from_date à to_date .

date_aves = (from_date..to_date).map{|dt| [dt, 0]}

Cela construit la liste complète des dates sous forme de tableau. Nous n'avons pas besoin des dates où nous avons obtenu une moyenne :

ave_price_dates = ave_prices.collect{|ave_price| ave_price[0]} # build an array of dates
date_aves.delete_if { |dt| ave_price.dates.index(dt[0]) } # remove zero entries for dates retrieved from DB
date_aves.concat(ave_prices)     # add the query results
date_aves.sort_by{|ave| ave[0] } # sort by date

Ce lot me semble un peu encombré :je pense qu'il pourrait être plus concis et plus propre. J'étudierais la construction d'un Hash ou d'un Struct plutôt que de rester dans des tableaux.

[1] Je ne dis pas de ne pas utiliser SQL - des situations se produisent où ActiveRecord ne peut pas générer la requête la plus efficace et vous vous rabattez sur find_by_sql . C'est bien, c'est censé être comme ça, mais je pense que vous ne devriez essayer de l'utiliser qu'en dernier recours.