如何使用 Active Record 查找具有重复数据的记录

Posted

技术标签:

【中文标题】如何使用 Active Record 查找具有重复数据的记录【英文标题】:How to find records that have duplicate data using Active Record 【发布时间】:2011-07-03 15:07:56 【问题描述】:

使用 ruby​​ 和新的 Activerecord 在列中查找具有重复值的记录的最佳方法是什么?

【问题讨论】:

只有 1 列或多于 1 列的重复值?是/是这些字符串/整数/文本字段吗? 只有 1 列 - 字符串。 【参考方案1】:

将@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")

【讨论】:

这段代码是否也适用于 PostgreSQL?它返回错误PGError: ERROR: column "quantity" does not exist @Marc,我不确定。不过你可以试试Type.select("id, count(id) as quantity").group(:name).having("count(id) > 1") 这只会找到完全相同的重复项。 @holaSenor - 什么是不完全重复的,究竟是什么? (双关语) 问得好,我相信这在当时是有道理的。我怀疑还有另一条评论,自删除后,我也在回复。可能是带有一些代码的注释,它比较了行中的所有字段而不是一列,但谁知道呢。重复需要通过一些标准来限定。确切地说,我认为我的意思是建议的代码比较了所有属性,它们必须相同,OP 想使用一列。【参考方案2】:

以下是我使用 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 值的记录,并告诉您有多少个姓氏以及哪些姓氏在一个不错的哈希中。

【讨论】:

【参考方案3】:

我正在用 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

【讨论】:

这正是我所需要的【参考方案4】:

使用自定义 SQL,这会发现 typesname 的值相同:

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

【讨论】:

【参考方案5】:

在 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")

【讨论】:

这里完全偏离主题,挖坟评论......但为什么这比 SQL 更好? @JohnCromartie 不是。但这很有趣。 ;)【参考方案6】:

这是一个扩展其他答案的解决方案,以显示如何查找和遍历按重复字段分组的记录:

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

这似乎很遗憾,这必须通过两个查询来完成,但this answer 确认了这种方法。

【讨论】:

以上是关于如何使用 Active Record 查找具有重复数据的记录的主要内容,如果未能解决你的问题,请参考以下文章

具有完全迁移支持的 .net Active Record ORM

复杂Rails Active Record查询选择具有真实结果的记录,以便当天最新更新其他创建的记录

如何使用 Active Record 回滚特定数据库

如何使用 Ruby Active Record 获取 sql 脚本的输出?

如何在表单中使用 Active Record 枚举单选按钮?

Ruby on Rails。如何在 :belongs to 关系中使用 Active Record .build 方法?