Qual é a melhor maneira de encontrar registros com valores duplicados em várias colunas usando Postgres e Activerecord?
Encontrei esta solução aqui :
User.find(:all, :group => [:first, :email], :having => "count(*) > 1" )
Mas não parece funcionar com postgres. Estou recebendo este erro:
PG :: GroupingError: ERROR: a coluna "parts.id" deve aparecer na cláusula GROUP BY ou ser usada em uma função agregada
ruby-on-rails
postgresql
activerecord
newUserNameHere
fonte
fonte
select a.id, b.id, name, email FROM user a INNER JOIN user b USING (name, email) WHERE a.id > b.id
. Não faço ideia de como expressar isso na linguagem ActiveRecord.Respostas:
Versão testada e de trabalho
Além disso, isso é um pouco independente, mas útil. Se você quiser ver quantas vezes cada combinação foi encontrada, coloque .size no final:
e você obterá um conjunto de resultados semelhante a este:
Achei muito legal e não tinha visto antes.
Crédito para Taryn, esta é apenas uma versão ajustada de sua resposta.
fonte
select()
como em:User.select([:first,:email]).group(:first,:email).having("count(*) > 1").count
para funcionar..count
dáPG::UndefinedFunction: ERROR: function count
.size
vez de.count
Esse erro ocorre porque POSTGRES requer que você coloque colunas de agrupamento na cláusula SELECT.
experimentar:
(nota: não testado, pode ser necessário ajustá-lo)
EDITADO para remover coluna id
fonte
id
coluna não faz parte do grupo, portanto você não pode referenciá-la a menos que a agregue (por exemplo,array_agg(id)
oujson_agg(id)
)Se você precisar dos modelos completos, tente o seguinte (com base na resposta de @ newUserNameAqui).
Isso retornará as linhas em que o endereço de e-mail da linha não é exclusivo.
Não conheço uma maneira de fazer isso com vários atributos.
fonte
.select(:email)
é redundante. Acho que isso é um pouco mais limpo, mas posso estar errado.User.where(email: User.select(:email).group(:email).having("count(*) > 1"))
Obtenha todas as duplicatas com uma única consulta se usar PostgreSQL :
fonte
Com base na resposta de @newUserNameAqui, acredito que a maneira certa de mostrar a contagem de cada um é
fonte