Как найти записи с дублирующимися данными с помощью Active Record - PullRequest
26 голосов
/ 24 февраля 2011

Каков наилучший способ поиска записей с повторяющимися значениями в столбце с использованием ruby ​​и новой Activerecord?

Ответы [ 6 ]

50 голосов
/ 24 февраля 2011

Перевод @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")
24 голосов
/ 12 июля 2012

Вот как я решил это с помощью помощников AREL, а не с пользовательским SQL:

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 и сообщает вам, сколько и какие фамилии в хорошем хэше.

13 голосов
/ 11 августа 2016

Я бился головой об этой проблеме со стеком 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}
11 голосов
/ 24 февраля 2011

С пользовательским SQL это находит types с такими же значениями для name:

sql = 'SELECT id, COUNT(id) as quantity FROM types
         GROUP BY name HAVING quantity > 1'
repeated = ActiveRecord::Base.connection.execute(sql)
5 голосов
/ 04 апреля 2011

В 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")
1 голос
/ 10 июля 2018

Вот решение, которое расширяет другие ответы, чтобы показать, как найти и перебрать записи, сгруппированные по дублирующему полю:

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

Кажется, стыдно, что это нужно делать с двумя запросами, но этот ответ подтверждает этот подход.

...