查找具有重复名称的所有用户
我有拥有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以深入了解问题。