sql >> Database >  >> RDS >> Mysql

De beste manier in MySQL of Rails om AVG per dag binnen een specifiek datumbereik te krijgen

Is er een reden (buiten de reeds genoemde datum) waarom u de ingebouwde groepsfunctiemogelijkheden in ActiveRecord niet zou gebruiken? Je lijkt je zorgen te maken over "nabewerking", wat volgens mij niet echt iets is om je zorgen over te maken.

Je bent in Rails, dus je moet waarschijnlijk eerst op zoek naar een Rails-oplossing [1]. Mijn eerste gedachte zou zijn om iets te doen als

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

die ActiveRecord heeft omgezet in vrijwel de SQL die u beschreef. Ervan uitgaande dat er een verklaarde has_many . is associatie tussen verkoper en product, dan kunt u die waarschijnlijk beter gebruiken, dus zoiets als:

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

(Ik hoop dat je beschrijving van het model als "products_sold" een soort transcriptiefout is, trouwens - zo niet, dan ben je een beetje verkeerd met de naamgeving van je klas!)

Na dat alles ben je terug waar je begon, maar je kwam daar op een meer conventionele manier (en Rails hecht echt waarde aan conventies!). Nu moeten we de gaten opvullen.

Ik neem aan dat u uw datumbereik kent, laten we zeggen dat het is gedefinieerd als alle datums van from_date tot to_date .

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

Dat bouwt de volledige lijst met datums op als een array. We hebben de datums waarop we een gemiddelde kregen niet nodig:

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

Dat perceel ziet er een beetje rommelig uit voor mij:ik denk dat het beknopter en schoner kan. Ik zou onderzoeken hoe je een Hash of Struct kunt bouwen in plaats van in arrays te blijven.

[1] Ik zeg niet dat je geen SQL moet gebruiken - er doen zich situaties voor waarin ActiveRecord niet de meest efficiënte query kan genereren en je terugvalt op find_by_sql . Dat is prima, het zou zo moeten zijn, maar ik denk dat je moet proberen het alleen als laatste redmiddel te gebruiken.



  1. PostgreSQL - GROUP BY-clausule of worden gebruikt in een aggregatiefunctie

  2. SQL Blijf fouten krijgen met ON UPDATE CASCADE

  3. Query om de som van de afstand (lengtegraad, breedtegraad) in opeenvolgende rijen in Mysql . te berekenen

  4. Dichtstbijzijnde, deel 3