Como posso contar o número de registros que possuem um valor exclusivo em um determinado campo no ROR?

StackOverflow https://stackoverflow.com/questions/36608

Pergunta

Tenho um conjunto de registros que inclui um campo de data e desejo determinar quantas datas exclusivas estão representadas no conjunto de registros.

Algo como:

Record.find(:all).date.unique.count 

mas é claro que isso não parece funcionar.

Foi útil?

Solução

O que você está procurando é o seguinte SQL:

SELECT COUNT(DISTINCT date) FROM records

ActiveRecord tem isso integrado:

Record.count('date', :distinct => true)

Outras dicas

Isso mudou ligeiramente nos trilhos 4 e superiores :distinct => true agora está obsoleto.Usar:

Record.distinct.count('date')

Ou se você quiser a data e o número:

Record.group(:date).distinct.count(:date)

Fora do SQL:

Record.find(:all).group_by(&:date).count

ActiveSupport Enumerável#group_by é indispensável.

o mais recente #count no código-fonte do Rails aceita apenas 1 parâmetro.ver: http://api.rubyonrails.org/classes/ActiveRecord/Calculations.html#method-i-count

então eu alcancei o requisito

Record.count('DISTINCT date')

Detalhando a resposta:

Post.create(:user_id => 1, :created_on => '2010-09-29')
Post.create(:user_id => 1, :created_on => '2010-09-29')
Post.create(:user_id => 2, :created_on => '2010-09-29')
Post.create(:user_id => null, :created_on => '2010-09-29')

Post.group(:created_on).count
# => {'2010-09-29' => 4}

Post.group(:created_on).count(:user_id)
# => {'2010-09-29' => 3}

Post.group(:created_on).count(:user_id, :distinct => true) # Rails <= 3
Post.group(:created_on).distinct.count(:user_id) # Rails = 4
# => {'2010-09-29' => 2}

Como mencionei aqui, no Rails 4, usando (...).uniq.count(:user_id) como mencionado em outras respostas (para esta pergunta e em outras partes do SO), na verdade levará a um extra DISTINCT estando na consulta:

SELECT DISTINCT COUNT(DISTINCT user_id) FROM ...

O que realmente precisamos fazer é usar nós mesmos uma string SQL:

(...).count("DISTINCT user_id")

O que nos dá:

SELECT COUNT(DISTINCT user_id) FROM ...

Além disso, certifique-se de ter um índice no campo em seu banco de dados, caso contrário a consulta ficará lenta rapidamente.

(É muito melhor fazer isso em SQL, caso contrário você coloca toda a tabela db na memória apenas para responder a contagem.)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top