如何使用postgresql在Rails中执行不区分大小写的顺序

bra*_*rad 52 ruby postgresql ruby-on-rails sql-order-by case-insensitive

我正在将我的开发环境从sqlite3切换到postgresql 8.4并且有最后一个障碍.

在我的原始中,我在辅助方法中有以下行;

result = Users.find(:all, :order => "name collate NOCASE")
Run Code Online (Sandbox Code Playgroud)

这提供了一个非常好的不区分大小写的搜索.我不能为postgresql复制这个.应该很容易 - 任何想法?

谢谢.

Lan*_*ceH 80

result = Users.find(:all, :order => "LOWER(name)")
Run Code Online (Sandbox Code Playgroud)

从布拉德和弗兰克那里得到一点点.

  • 小心默认范围.即使他们看起来是一个非常好的主意,但他们经常会咬你的屁股.建立一个特定的范围,如`by_name`或`alpha`,并在任何地方使用它可能不会像干,但更容易改变道路.只是值得深思 (3认同)
  • 我采用的一种更极端的解决方案是使用额外的列跟踪原始列.在插入或更新时使用触发器,修改该列.我过去曾经用过这几次,在那里我想对某些东西进行排序,并且不想要"a,an,the"的主要词语.我也剥夺了所有特殊字符.这导致"标题","标题","!标题","标题"彼此相邻排序而不是分散.它还可以编辑可排序字段,这样我就可以在"标题IX"之前制作"标题V". (2认同)

Tho*_*emm 24

LanecH的答案适用于Rails 3+(包括Rails 4和5):

users = User.order('LOWER(name)')
Run Code Online (Sandbox Code Playgroud)

或者创建一个可以重用的命名范围:

class User < ActiveRecord::Base
  scope :order_by_name, -> { order('LOWER(name)') }
end

users = User.order_by_name
Run Code Online (Sandbox Code Playgroud)


Mar*_*rez 21

现在使用Rails 5.2,如果使用接受的答案,您可能会收到警告.

DEPRECATION WARNING:使用非属性参数调用的危险查询方法(其参数用作原始SQL的方法):"LOWER(?)ASC".

另一种选择可能是依赖Arel(它现在合并到Rails中):

results = User.order(User.arel_table['name'].lower.asc)
# results.to_sql == "SELECT \"users\".* FROM \"users\" ORDER BY LOWER(\"users\".\"name\") ASC" 
Run Code Online (Sandbox Code Playgroud)

  • 或者只使用results = User.order(Arel.sql('lower(name)').如果你知道你的SQL,它会更容易理解. (7认同)

rfu*_*sca 6

您是否考虑过将列存储为citext类型?根据我的理解,它真的只是内部化对lower()的调用.之后对你来说会是自动的.如果有时您需要区分大小写的搜索,这可能不是最好的主意.


Fra*_*ens 5

在SQL中,您可以使用ORDER BY LOWER(columnname),不知道如何在Ruby中执行此操作.功能索引(也在LOWER(列名)上)将有助于加快速度.