web-dev-qa-db-fra.com

Comment trouver des enregistrements contenant des données en double à l'aide d'Active Record

Quel est le meilleur moyen de rechercher des enregistrements avec des valeurs en double dans une colonne à l'aide de Ruby et du nouvel Activerecord?

26
srboisvert

Traduire @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")
50
fl00r

Voici comment j'ai résolu le problème avec les assistants AREL et aucun SQL personnalisé:

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} }

Vraiment, c'est juste une façon plus agréable d'écrire le code SQL. Cela permet de rechercher tous les enregistrements ayant des valeurs nom_fichier en double et d’indiquer le nombre et le nom des derniers noms dans un hachage Nice.

24
brookr

Je battais la tête contre ce problème avec un stack de 2016 (Rails 4.2, Ruby 2.2), et j'ai obtenu ce que je voulais avec ceci:

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

Avec SQL personnalisé, ceci trouve types avec les mêmes valeurs pour name:

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

Dans Rails 2.x, select est une méthode privée de la classe AR. Il suffit d'utiliser find ():

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

Voici une solution qui étend les autres réponses pour montrer comment rechercher et parcourir les enregistrements groupés par le champ en double:

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

Il semble dommage que cela doive être fait avec deux requêtes mais cette réponse confirme cette approche.

0
eremite