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

Rails - Extraction et calcul efficaces de données sur plusieurs relations

Pour obtenir une liste d'identifiants d'utilisateur avec plus d'un achat, vous pouvez procéder comme suit, ce qui n'accédera qu'à un seul tableau :

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

Par la suite, vous pourrez récupérer tous ces utilisateurs avec :

users = User.find user_ids

Les choses peuvent être accélérées avec un contre-cache. Dans votre modèle utilisateur, ajoutez l'option :counter_cache => true au has_many association pour les offres achetées. Vous aurez besoin d'une colonne d'entiers supplémentaire sur votre table d'utilisateurs et d'initialisation, qui pourrait ressembler à ceci dans une migration :

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

Une fois cela réglé, cela devient beaucoup plus simple :

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

Rails gardera la colonne à jour pour vous, avec la plupart des opérations standard.

Obtenir le prix total impliquera toujours une jointure. Ou vous pouvez créer un hachage des prix des transactions et effectuer le traitement fastidieux dans Ruby. Je ne suis pas un expert SQL, mais vous pouvez potentiellement vous débarrasser de la jointure en stockant le prix avec PurchasedDeal. Sinon, voici comment procéder avec une jointure :

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

Vous pouvez filtrer cela uniquement sur les utilisateurs de votre choix en ajoutant quelque chose comme :conditions => ['user_id IN (?)', users] . (Où les users peut être une liste d'ID, mais aussi des objets Utilisateur.)