查找具有重复名称的所有用户

我有拥有first_name和last_name字段的用户,我需要做一个ruby,根据名字和姓氏找到所有拥有重复帐户的用户。 例如,我希望有一个搜索将搜索所有其他用户,并查找是否有任何相同的名称和电子邮件。 我在想这样的嵌套循环

User.all.each do |user| //maybe another loop to search through all the users and maybe if a match occurs put that user in an array end 

有没有更好的办法

您可以通过首先找出重复数据的内容来缩小搜索范围。 例如,假设您要查找多次使用的名字和电子邮件的每个组合。

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

这将返回一个包含每个重复记录之一的数组。 从那里,假设其中一个返回的用户有“Fred”和“fred@example.com”,那么您只能搜索具有这些值的用户来查找所有受影响的用户。

find的回报将如下所示。 请注意,该数组仅包含每组重复用户的单个记录。

 [#, #] 

例如,该数组中的第一个元素显示一个用户具有“foo”和“foo@example.com”。 其余的可以根据需要通过查找从数据库中取出。

 > User.find(:all, :conditions => {:email => "foo@example.com", :first => "foo"}) => [#, #] 

而且您似乎还希望为代码添加一些更好的validation,以防止将来出现重复。

编辑:

如果你需要使用find_by_sql大锤,因为Rails 2.2和更早版本不支持:having拥有find ,以下应该可以工作,并为你提供我上面描述的相同数组。

 User.find_by_sql("select * from users group by first,email having count(*) > 1") 

经过一些谷歌搜索,我最终得到了这个:

 ActiveRecord::Base.connection.execute(<<-SQL).to_a SELECT variants.id, variants.variant_no, variants.state FROM variants INNER JOIN ( SELECT variant_no, state, COUNT(1) AS count FROM variants GROUP BY variant_no, state HAVING COUNT(1) > 1 ) tt ON variants.variant_no = tt.variant_no AND variants.state IS NOT DISTINCT FROM tt.state; SQL 

注意那个表示IS NOT DISTINCT FROM ,这是为了帮助处理NULL值,这些值无法与postgres中的equals符号进行比较。

如果您要使用@hakunin的路线并手动创建查询,您可能希望使用以下内容:

 ActiveRecord::Base.connection.exec_quey(<<-SQL).to_a SELECT variants.id, variants.variant_no, variants.state FROM variants INNER JOIN ( SELECT variant_no, state, COUNT(1) AS count FROM variants GROUP BY variant_no, state HAVING COUNT(1) > 1 ) tt ON variants.variant_no = tt.variant_no AND variants.state IS NOT DISTINCT FROM tt.state; SQL 

更改是用connection.execute(<<-SQL)替换connection.exec_query(<<-SQL)

使用execute可能存在内存泄漏问题

请阅读Clarify DataBaseStatements #execute以深入了解问题。