Mysql
 sql >> Database >  >> RDS >> Mysql

Rails:estrae e calcola in modo efficiente i dati attraverso diverse relazioni

Per ottenere un elenco di ID utente con più di un acquisto, puoi fare quanto segue, che accederà a una sola tabella:

user_ids = PurchasedDeal.count(:group => :user_id, :having => 'count_all > 0').keys

Successivamente, puoi recuperare tutti questi utenti con:

users = User.find user_ids

Le cose possono essere velocizzate con una cache del contatore. Nel tuo modello utente, aggiungi l'opzione :counter_cache => true a has_many associazione per le offerte acquistate. Avrai bisogno di una colonna intera aggiuntiva nella tabella degli utenti e inizializza, che potrebbe apparire come segue in una migrazione:

add_column :users, :purchased_deals_count, :integer, :null => false, :default => 0
User.each { |u| User.reset_counters u, :purchased_deals }

Una volta che è fuori mano, diventa molto più semplice:

users = User.all :conditions => 'purchased_deals_count > 0'

Rails manterrà la colonna aggiornata per te, con la maggior parte delle operazioni standard.

Per ottenere il prezzo totale comporterà sempre un join. Oppure puoi creare un hash dei prezzi delle offerte ed eseguire la noiosa elaborazione in Ruby. Non sono un esperto di SQL, ma puoi potenzialmente sbarazzarti del join memorizzando il prezzo con PurchasedDeal. Altrimenti, ecco come farlo con un join:

user_id_to_price = PurchasedDeal.sum 'deal.price', :include => :deal, :group => :user_id

Puoi filtrarlo solo sugli utenti che desideri aggiungendo qualcosa come :conditions => ['user_id IN (?)', users] . (Dove users può essere un elenco di ID, ma anche oggetti Utente.)