¿Cuál es la mejor manera de encontrar registros con valores duplicados en múltiples columnas usando Postgres y Activerecord?
Encontré esta solución aquí :
User.find(:all, :group => [:first, :email], :having => "count(*) > 1" )
Pero no parece funcionar con postgres. Recibo este error:
PG :: GroupingError: ERROR: la columna "parts.id" debe aparecer en la cláusula GROUP BY o usarse en una función agregada
ruby-on-rails
postgresql
activerecord
newUserNameHere
fuente
fuente
select a.id, b.id, name, email FROM user a INNER JOIN user b USING (name, email) WHERE a.id > b.id
. No tengo idea de cómo expresar eso en ActiveRecord-speak.Respuestas:
Versión probada y funcional
Además, esto no está relacionado pero es útil. Si desea ver cuántas veces se encontró cada combinación, coloque .size al final:
y obtendrás un conjunto de resultados que se ve así:
Pensé que era bastante bueno y no lo había visto antes.
Gracias a Taryn, esta es solo una versión modificada de su respuesta.
fuente
select()
como en:User.select([:first,:email]).group(:first,:email).having("count(*) > 1").count
para que funcione..count
donacionesPG::UndefinedFunction: ERROR: function count
.size
lugar de.count
Ese error se produce porque POSTGRES requiere que coloque columnas de agrupación en la cláusula SELECT.
tratar:
(nota: no probado, es posible que deba modificarlo)
EDITADO para eliminar la columna de identificación
fuente
id
columna no es parte del grupo, por lo que no puede referirla a menos que la agregue (por ejemplo,array_agg(id)
ojson_agg(id)
)Si necesita los modelos completos, intente lo siguiente (según la respuesta de @ newUserNameHere).
Esto devolverá las filas donde la dirección de correo electrónico de la fila no es única.
No conozco una forma de hacer esto con múltiples atributos.
fuente
.select(:email)
es redundante. Creo que esto es un poco más limpio, pero podría estar equivocado.User.where(email: User.select(:email).group(:email).having("count(*) > 1"))
Obtenga todos los duplicados con una sola consulta si usa PostgreSQL :
fuente
Según la respuesta anterior de @newUserNameHere, creo que la forma correcta de mostrar el recuento de cada uno es
fuente