Quelle est la meilleure façon de rechercher des enregistrements avec des valeurs en double sur plusieurs colonnes à l'aide de Postgres et Activerecord?
J'ai trouvé cette solution ici :
User.find(:all, :group => [:first, :email], :having => "count(*) > 1" )
Mais cela ne semble pas fonctionner avec postgres. J'obtiens cette erreur:
PG :: GroupingError: ERROR: la colonne "parts.id" doit apparaître dans la clause GROUP BY ou être utilisée dans une fonction d'agrégation
ruby-on-rails
postgresql
activerecord
newUserNameHere
la source
la source
select a.id, b.id, name, email FROM user a INNER JOIN user b USING (name, email) WHERE a.id > b.id
. Je ne sais pas comment exprimer cela dans ActiveRecord-speak.Réponses:
Version testée et fonctionnelle
En outre, c'est un peu sans rapport mais pratique. Si vous voulez voir combien de fois chaque combinaison a été trouvée, mettez .size à la fin:
et vous obtiendrez un jeu de résultats qui ressemble à ceci:
J'ai pensé que c'était plutôt cool et je ne l'avais jamais vu auparavant.
Merci à Taryn, ce n'est qu'une version modifiée de sa réponse.
la source
select()
as in:User.select([:first,:email]).group(:first,:email).having("count(*) > 1").count
pour travailler..count
donnePG::UndefinedFunction: ERROR: function count
.size
place de.count
Cette erreur se produit car POSTGRES vous oblige à placer des colonnes de regroupement dans la clause SELECT.
essayer:
(note: non testé, vous devrez peut-être le modifier)
MODIFIÉ pour supprimer la colonne d'identifiant
la source
id
colonne ne fait pas partie du groupe, vous ne pouvez donc pas la référer à moins de l'agréger (par exemplearray_agg(id)
oujson_agg(id)
)Si vous avez besoin des modèles complets, essayez ce qui suit (basé sur la réponse de @ newUserNameHere).
Cela renverra les lignes où l'adresse e-mail de la ligne n'est pas unique.
Je ne connais pas un moyen de le faire sur plusieurs attributs.
la source
.select(:email)
est redondant. Je pense que c'est un peu plus propre, mais je peux me tromper.User.where(email: User.select(:email).group(:email).having("count(*) > 1"))
Obtenez tous les doublons avec une seule requête si vous utilisez PostgreSQL :
la source
Basé sur la réponse ci-dessus par @newUserNameIci, je crois que la bonne façon d'afficher le décompte pour chacun est
la source