web-dev-qa-db-ja.com

Active Recordを使用してデータが重複しているレコードを見つける方法

Rubyと新しいActiverecordを使用して列内の重複する値を持つレコードを検索する最良の方法は何ですか?

27
srboisvert

@TuteCを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

カスタムSQLを使用せずにARELヘルパーで解決した方法を次に示します。

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

本当に、それはSQLを書くためのより良い方法です。これにより、last_name値が重複しているすべてのレコードが検索され、Niceハッシュに含まれる姓と名前の数がわかります。

24
brookr

私はこの問題に対して2016スタック(Rails 4.2、Ruby 2.2))で頭をぶつけていて、これで私が望んでいたものを得ました:

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

カスタムSQLでは、typesと同じ値を持つnameを検索します。

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

Rails 2.xでは、selectはARクラスのプライベートメソッドです。find()を使用するだけです。

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

以下は、他の回答を拡張して、重複フィールドでグループ化されたレコードを検索して反復する方法を示すソリューションです。

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

2つのクエリでこれを行う必要があるのは残念ですが、 この答え はこのアプローチを確認します。

1
eremite