4

我试图找到超过 3M 的表,所有具有相同用户名的用户。我读过这样的东西可能会奏效。

User.find(:all, :group => [:username], :having => "count(*) > 1" )

但是,由于我使用的是 Postgres,所以这返回了 me ActiveRecord::StatementInvalid: PG::Error: ERROR: column "users.id" must appear in the GROUP BY clause or be used in an aggregate function

我正在尝试这样的事情

User.select('users.id, users.username').having("count(*) > 1").group('users.username')

但仍然得到同样的错误。知道我做错了什么吗?

更新:我让它以某种方式工作,User.select('users.*').group('users.id').having('count(users.username) > 1')但这个查询返回给我这个看起来像一个空数组,即使是创建 5 条记录。

 GroupAggregate  (cost=9781143.40..9843673.60 rows=3126510 width=1365)
   Filter: (count(username) > 1)
   ->  Sort  (cost=9781143.40..9788959.68 rows=3126510 width=1365)
         Sort Key: id
         ->  Seq Scan on users  (cost=0.00..146751.10 rows=3126510 width=1365)
(5 rows)

 => [] 

知道为什么会发生这种情况以及如何获得这 5 行吗?

4

2 回答 2

5

我认为你能得到的最好的方法是获取重复记录的用户名。这可以通过

User.select(:username).group(:username).having('COUNT(username) > 1')
于 2013-07-12T19:37:04.770 回答
0

数据库中的“group by”将每个组折叠成输出中的一行。以下查询很可能会产生您想要的内容:

    User.where("name in (select name from users group by name having count(*)>1)").order(:name)

上面的内部查询查找所有出现多次的名称。然后我们找到所有具有这些名称的行。按名称订购将使您的进一步处理更容易。为了加快速度,将索引添加到 users 表中的列名。

有替代 Postgres 特定的方法来解决这个问题,但是上述方法适用于所有数据库。

于 2013-07-14T19:14:16.330 回答