【问题标题】:Rails / SQL: Find attributes with same value but different capitalizationRails / SQL:查找具有相同值但大小写不同的属性
【发布时间】:2012-10-23 16:28:09
【问题描述】:

这可能真的很基本,但我想不出如何编写一个 SQL 查询来查找具有相同字符但大小写不同的字符串。

我正在处理的上下文是 Rails 3.2 应用程序。我有一个带有 Name 属性的简单 Tag 模型。我继承了这个模型的数据,它不区分大小写存储值,所以一些用户输入诸如“树”之类的内容,而其他用户输入“树”,现在我们有两个标签,应该是一个。

所以,我想做一个查询来找到所有这些对,以便我可以合并它们。

到目前为止,我唯一能想到的就是编写一个 rake 任务,循环遍历它们并检查匹配的值......类似于:

pairs = []
Tag.all.each do |t|
  other = Tag.where( 'name LIKE ?', t.name )
  pairs << [t, other] if other
end

但是,我不确定上述方法是否可行,或者在性能方面是否有意义。有没有更好的方法来编写可以找到这些匹配对的 SQL 查询?

【问题讨论】:

    标签: sql ruby-on-rails case-insensitive


    【解决方案1】:

    有一个类似的问题here

    您可以做的是在您的模型中创建一个方法来执行不区分大小写的搜索。然而,根据我的经验,ActiveRecord 已经进行了不区分大小写的搜索,但以防万一:

    def self.insensitive_find_by_tag_name(name)
        Tag.where("lower(name) = ? ", name.downcase)
    end
    

    然后要删除重复的条目,您可以这样做

    Tag.transaction! do
        tags = Tag.insensitive_find_by_tag_name(name)
    
        tags.last(tags.length() - 1).each do |tag|
            tag.destroy        
        end
    end
    

    调用事务以防万一发生故障,以便数据库回滚。抓取所有具有相同名称的标签,然后删除任何额外的条目。如果您希望剩余的标签条目为小写,那么您可以这样做

    tag = tags.first
    tag.name = tag.name.downcase
    tag.save!
    

    【讨论】:

    • 我最终做了一些与此非常相似的事情,而且效果很好。谢谢!
    【解决方案2】:

    我不太擅长 SQL,但我对此进行了一些研究,发现使用 COLLATE 子句可以使 SQL 中的字符串操作区分大小写。 (通常选择不同的操作不区分大小写。)

    所以也许你可以试试:

    select distinct (name) COLLATE sql_latin1_general_cp1_cs_as
        FROM (
        ... blah blah blah
    

    以下是整理的一些文档: http://dev.mysql.com/doc/refman/5.0/en/charset-collate.html

    (假设你使用的是 mysql 我猜)

    或者,您也可以通过整理将数据库重新配置为区分大小写。那么您当前的查询可能不会改变

    (假设您具有管理权限和重新配置的能力)

    【讨论】:

    • FWIW 我正在使用 PostgreSQL。我会研究一下 Collat​​e 看看我是否能理解它:)
    【解决方案3】:

    您应该使用 upper() 或 lower() 函数将名称全部转换为小写或大写。

    SELECT DISTINCT upper(name)
    

    或者:

    SELECT DISTINCT lower(name)
    

    来源:http://www.postgresql.org/docs/9.1/static/functions-string.html

    另一个选项(更好的代码可维护性)是使用 CITEXT 类型,但要这样做,您必须修改表结构:http://www.postgresql.org/docs/9.1/static/citext.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-09-01
      • 1970-01-01
      • 1970-01-01
      • 2022-07-06
      • 2023-02-14
      • 2022-08-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多