Comment puis-je compter le nombre d'enregistrements qui ont une valeur unique dans un champ particulier du ROR ?
-
09-06-2019 - |
Question
J'ai un jeu d'enregistrements qui comprend un champ de date et je souhaite déterminer combien de dates uniques sont représentées dans le jeu d'enregistrements.
Quelque chose comme:
Record.find(:all).date.unique.count
mais bien sûr, cela ne semble pas fonctionner.
La solution
Ce que vous recherchez est le SQL suivant :
SELECT COUNT(DISTINCT date) FROM records
ActiveRecord a ceci intégré :
Record.count('date', :distinct => true)
Autres conseils
Cela a légèrement changé dans les rails 4 et supérieurs :distinct => true
est désormais obsolète.Utiliser:
Record.distinct.count('date')
Ou si vous voulez la date et le numéro :
Record.group(:date).distinct.count(:date)
En dehors de SQL :
Record.find(:all).group_by(&:date).count
ActiveSupport Énumérable#group_by est indispensable.
le dernier #count
le code source sur Rails n'accepte qu'un seul paramètre.voir: http://api.rubyonrails.org/classes/ActiveRecord/Calculations.html#method-i-count
j'ai donc atteint l'exigence en
Record.count('DISTINCT date')
Détaillant la réponse:
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}
Comme je l'ai mentionné ici, dans Rails 4, en utilisant (...).uniq.count(:user_id)
comme mentionné dans d'autres réponses (pour cette question et ailleurs sur SO), cela entraînera en fait un supplément DISTINCT
étant dans la requête :
SELECT DISTINCT COUNT(DISTINCT user_id) FROM ...
Ce que nous devons faire, c'est utiliser nous-mêmes une chaîne SQL :
(...).count("DISTINCT user_id")
Ce qui nous donne :
SELECT COUNT(DISTINCT user_id) FROM ...
Assurez-vous également d'avoir un index sur le champ dans votre base de données, sinon cette requête deviendra rapidement lente.
(C'est bien mieux de faire cela en SQL, sinon vous mettez toute la table de base de données en mémoire juste pour répondre au décompte.)