如何在select查询rails或sql查询中使用trim

时间:2015-03-10 11:23:52

标签: mysql ruby-on-rails sql-server

User.select(:name).group(:name).having("count(*) > 1")

此查询可以正常选择具有重复用户名的记录。但面临的问题是名称中有空间。

例如。

recoed1 = "Username"
record2 = "Username "

这是两条记录,但它们具有相同的名称,但上面的查询将它们视为不同的记录,因为第二条记录中有空格。所以在选择时我没有得到这个记录。

任何使用普通mysql查询或rails的解决方案都可以。

OR

如何使用rails / mysql查询首先从表中剥离或修剪所有列数据。然后我可以申请以上查询。

2 个答案:

答案 0 :(得分:1)

您可以使用mysql's string functions

User.select("lower(trim(name))").group("lower(trim(name))").having("count(*) > 1")

答案 1 :(得分:0)

我在这里要做的是确保您的数据首先是整洁的。

您可以使用预验证方法在用户名上调用strip。你可以这样做

#in lib/trimmer.rb
module Trimmer
  # Make a class method available to define space-trimming behavior.
  def self.included base
    base.extend(ClassMethods)
  end

  module ClassMethods
    # Register a before-validation handler for the given fields to
    # trim leading and trailing spaces.
    def trimmed_fields *field_list
      before_validation do |model|
        field_list.each do |field|
          model.send("#{field}=", model.send("#{field}").strip) if model.send("#{field}").respond_to?('strip')
        end
      end
    end
  end
end

确保此模块是必需的,无论您在配置中需要lib中的内容。

现在,你可以说,在任何模型中都是这样的(在这个例子中,我正在做除了用户名之外的其他一些领域)

class User < ActiveRecord::Base
  include Trimmer
  trimmed_fields :username, :email, :first_name, :last_name 
  ...

所以,这将解决你前进的问题。剩下的步骤是整理现有数据。我会在迁移中这样做。 (再次,我正在做一些其他领域作为例子)

tables_and_cols = {"users" => %w(username email first_name last_name), "foos" => %w(bar baz)}
tables_and_cols.each do |table, cols|
  cols.each do |col|
    ActiveRecord::Base.connection.execute("update #{tablename} set #{col} = trim(#{col})")
  end
end

现在,执行此修剪后,您可能会有一些重复的用户名。您将需要决定如何处理该问题,因为所涉及的记录不再有效。如果您还没有公开部署它,即如果您没有任何活跃的真实用户,那么无关紧要:您可以将用户名更改为其他用户名。但是,如果您确实有真正的人使用它,您可能需要更改其中一些用户名并通知他们。如果您想维持人们在用户名的开头或结尾不能有空格的情况,这是不可避免的。