Rails/SQL:查找值相同但大小写不同的属性

Rails/SQL:查找值相同但大小写不同的属性,sql,ruby-on-rails,case-insensitive,Sql,Ruby On Rails,Case Insensitive,这可能是非常基本的,但我想不出如何编写一个SQL查询来查找具有相同字符但大小写不同的字符串 我正在开发的环境是Rails 3.2应用程序。我有一个带有Name属性的简单标记模型。我继承了这个模型的数据,它不区分大小写存储值,所以一些用户输入“Tree”之类的东西,而其他用户输入“Tree”,现在我们有两个标签,它们实际上应该是一个 所以,我想做一个查询来找到所有这些对,这样我就可以合并它们了 到目前为止,我能想到的唯一一件事就是编写一个rake任务,在它们之间循环并检查匹配的值。。。比如: pa

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

我正在开发的环境是Rails 3.2应用程序。我有一个带有Name属性的简单标记模型。我继承了这个模型的数据,它不区分大小写存储值,所以一些用户输入“Tree”之类的东西,而其他用户输入“Tree”,现在我们有两个标签,它们实际上应该是一个

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

到目前为止,我能想到的唯一一件事就是编写一个rake任务,在它们之间循环并检查匹配的值。。。比如:

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

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

所以也许你可以试试:

select distinct (name) COLLATE sql_latin1_general_cp1_cs_as
    FROM (
    ... blah blah blah
以下是一些有关collate的文档:

(我想假设您使用的是mysql)

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

(假设您具有管理权限并能够重新配置)

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

SELECT DISTINCT upper(name)
或:

资料来源:


另一个选项(更好地维护代码)是使用CITEXT类型,但要做到这一点,您必须修改表结构:

有一个与此类似的问题

您可以做的是在您的模型中创建一个方法来进行不区分大小写的搜索。然而,根据我的经验,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!

FWIW我正在使用PostgreSQL。我将查看Collate,看看我是否能理解:)我最终做了一些非常类似的事情,而且效果很好。谢谢
tag = tags.first
tag.name = tag.name.downcase
tag.save!