2008-08-31 19 views

Respuesta

79

Lo que vamos a dar es el siguiente SQL:

SELECT COUNT(DISTINCT date) FROM records 

ActiveRecord ha esta construido en:

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

¿Es posible hacer esto usando varias columnas como un alcance? –

+13

Esto ahora está en desuso (rieles 4), vea la respuesta a continuación. – Yule

16

Fuera de SQL:

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

de ActiveSupport Enumerable#group_by es indispensable .

2

Además, asegúrese de tener un índice en el campo en su base de datos, de lo contrario esa consulta se convertirá rápidamente en poco útil.

(Es mucho mejor hacer esto en SQL, de lo contrario se tire toda la tabla db en la memoria sólo para responder a la cuenta.)

+1

La respuesta de nex3 generará correctamente la instrucción SQL 'COUNT'. http://guides.rubyonrails.org/active_record_querying.html#calculations – Kevin

+1

Sin embargo, es un buen consejo sobre el índice. – Kevin

82

Esto ha cambiado ligeramente en los carriles 4 y por encima de :distinct => true ahora está en desuso. Uso:

Record.distinct.count('date') 

O si desea que la fecha y el número:

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

No funciona para mí. Use '.count ('DISTINCT date')' – collimarco

+3

Terminé usando 'Record.group (: date) .count.count'. – jayp

8

Detallando la respuesta:

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} 
9

Como ya he mencionado here, en los carriles 4, usando (...).uniq.count(:user_id) como se ha mencionado en otras respuestas para esta pregunta (y en otros lugares en SO) en realidad llevar a un DISTINCT extra de estar en la consulta:

SELECT DISTINCT COUNT(DISTINCT user_id) FROM ...

Lo que realmente tenemos que hacer es usar una cadena SQL a nosotros mismos:

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

Lo que nos da:

SELECT COUNT(DISTINCT user_id) FROM ...

Cuestiones relacionadas