new*_*ere 93 postgresql activerecord ruby-on-rails
使用Postgres和Activerecord在多列中查找具有重复值的记录的最佳方法是什么?
我发现这个解决方案在这里:
User.find(:all, :group => [:first, :email], :having => "count(*) > 1" )
但它似乎不适用于postgres.我收到这个错误:
PG :: GroupingError:错误:列"parts.id"必须出现在GROUP BY子句中或用于聚合函数
new*_*ere 196
经过测试和工作的版本
User.select(:first,:email).group(:first,:email).having("count(*) > 1")
Run Code Online (Sandbox Code Playgroud)
此外,这有点无关但很方便.如果你想看看每个组合的发现时间,最后加上.size:
User.select(:first,:email).group(:first,:email).having("count(*) > 1").size
Run Code Online (Sandbox Code Playgroud)
然后你会得到一个如下所示的结果集:
{[nil, nil]=>512,
["Joe", "test@test.com"]=>23,
["Jim", "email2@gmail.com"]=>36,
["John", "email3@gmail.com"]=>21}
Run Code Online (Sandbox Code Playgroud)
认为这很酷,以前没见过.
感谢Taryn,这只是她答案的调整版本.
Tar*_*ast 30
发生该错误是因为POSTGRES要求您在SELECT子句中放置分组列.
尝试:
User.select(:first,:email).group(:first,:email).having("count(*) > 1").all
Run Code Online (Sandbox Code Playgroud)
(注意:未经测试,您可能需要调整它)
已编辑以删除id列
如果您需要完整型号,请尝试以下(基于@ newUserNameHere的答案).
User.where(email: User.select(:email).group(:email).having("count(*) > 1").select(:email))
Run Code Online (Sandbox Code Playgroud)
这将返回行的电子邮件地址不唯一的行.
我不知道在多个属性上执行此操作的方法.
如果您使用PostgreSQL ,则使用单个查询获取所有重复项:
def duplicated_users
duplicated_ids = User
.group(:first, :email)
.having("COUNT(*) > 1")
.select('unnest((array_agg("id"))[2:])')
User.where(id: duplicated_ids)
end
irb> duplicated_users
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
50712 次 |
最近记录: |