Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Rails - Extraia e calcule dados com eficiência em vários relacionamentos


Para obter uma lista de IDs de usuários com mais de uma compra, você pode fazer o seguinte, que acessará apenas uma tabela:
user_ids = PurchasedDeal.count(:group => :user_id, :having => 'count_all > 0').keys

Posteriormente, você pode buscar todos esses usuários com:
users = User.find user_ids

As coisas podem ser aceleradas com um cache de contador. Em seu modelo de usuário, adicione a opção :counter_cache => true para o has_many associação para negócios comprados. Você precisará de uma coluna inteira extra na tabela de usuários e inicializar, que pode ter a seguinte aparência em uma migração:
add_column :users, :purchased_deals_count, :integer, :null => false, :default => 0
User.each { |u| User.reset_counters u, :purchased_deals }

Uma vez que isso está fora do caminho, fica muito mais simples:
users = User.all :conditions => 'purchased_deals_count > 0'

O Rails manterá a coluna atualizada para você, com a maioria das operações padrão.

Para obter o preço total sempre envolverá uma adesão. Ou você pode criar um hash de preços de transação e fazer o processamento tedioso em Ruby. Não sou especialista em SQL, mas você pode se livrar da junção armazenando o preço com o PurchasedDeal. Caso contrário, veja como fazer isso com uma junção:
user_id_to_price = PurchasedDeal.sum 'deal.price', :include => :deal, :group => :user_id

Você pode filtrar isso apenas nos usuários que deseja adicionando algo como :conditions => ['user_id IN (?)', users] . (Onde users pode ser uma lista de IDs, mas também objetos User.)