ruby activerecord arel

ruby - Cómo encontrar registros que tienen datos duplicados utilizando Active Record



activerecord arel (6)

¿Cuál es la mejor manera de encontrar registros con valores duplicados en una columna usando ruby ​​y el nuevo Activerecord?


Aquí hay una solución que amplía las otras respuestas para mostrar cómo encontrar e iterar a través de los registros agrupados por el campo duplicado:

duplicate_values = Model.group(:field).having(Model.arel_table[:field].count.gt(1)).count.keys Model.where(field: duplicate_values).group_by(&:field).each do |value, records| puts "The records with ids #{records.map(&:id).to_sentence} have field set to #{value}" end

Parece una pena que haya que hacer esto con dos consultas, pero esta respuesta confirma este enfoque.


Así es como lo resolví con los ayudantes de AREL y sin SQL personalizado:

Person.select("COUNT(last_name) as total, last_name") .group(:last_name) .having("COUNT(last_name) > 1") .order(:last_name) .map{|p| {p.last_name => p.total} }

Realmente, es solo una forma más agradable de escribir el SQL. Encuentra todos los registros que tienen valores de last_name duplicados y te dice cuántos y cuáles son los apellidos en un buen hash.


Con SQL personalizado, encuentra types con los mismos valores para el name :

sql = ''SELECT id, COUNT(id) as quantity FROM types GROUP BY name HAVING quantity > 1'' repeated = ActiveRecord::Base.connection.execute(sql)


En Rails 2.x, seleccione es un método privado de clase AR. Solo usa find ():

klass.find(:all, :select => "id, count(the_col) as num", :conditions => ["extra conditions here"], :group => ''the_col'', :having => "num > 1")


Me estaba golpeando la cabeza contra este problema con una pila de 2016 (Rails 4.2, Ruby 2.2), y obtuve lo que quería con esto:

> Model.select([:thing]).group(:thing).having("count(thing) > 1").all.size => {"name1"=>5, "name2"=>4, "name3"=>3, "name4"=>2, "name5"=>2}


Traduciendo @TuteC en ActiveRecord:

sql = ''SELECT id, COUNT(id) as quantity FROM types GROUP BY name HAVING quantity > 1'' #=> Type.select("id, count(id) as quantity") .group(:name) .having("quantity > 1")