如果我有一个数字(例如88),我想在主ID列的Rails中执行LIKE查询,以返回ID末尾包含该数字的所有记录(IE:88,288等) 。),我该怎么做?这是生成结果的代码,在SQLLite中可以正常工作:
@item = Item.where("id like ?", "88").all
在PostgreSQL中,我遇到了这个错误:
PG::Error: ERROR: operator does not exist: integer ~~ unknown
我该怎么做?我已经尝试将数字转换为字符串,但这似乎也不起作用。
答案 0 :(得分:8)
LIKE
用于字符串/文本类型。由于您的主键是整数,因此您应该使用数学运算。
使用modulo获取id
值的剩余部分,除以100。
Item.where("id % 100 = 88")
这将返回Item
列以id
结尾的88
条记录
1288
1488
1238872388
862388
等...
如果您要动态执行此操作(例如,匹配任意两位数字,但您知道它总是两位数),您可以执行以下操作:
Item.where(["id % 100 = ?", last_two_digits)
如果你想匹配任意数量的数字,只要它们总是最后的数字(而不是出现在id
字段中其他位置的数字),你可以添加模型上的自定义方法。类似的东西:
class Item < ActiveRecord
...
def find_by_final_digits(num_digits, digit_pattern)
# Where 'num_digits' is the number of final digits to match
# and `digit_pattern` is the set of final digits you're looking fo
Item.where(["id % ? = ?", 10**num_digits, digit_pattern])
end
...
end
使用此方法,您可以找到以id
结尾的88
值,其中包含:
Item.find_by_final_digits(2, 88)
假设您想要查找以 id
和09
之间的数字结尾的所有12
值,无论出于何种原因。也许它们代表了你正在寻找的一些特殊代码范围。为此,您可以使用其他自定义方法使用Postgres“BETWEEN
查找范围。
def find_by_final_digit_range(num_digits, start_of_range, end_of_range)
Item.where(["id % ? BETWEEN ? AND ?", 10**num_digits, start_of_range, end_of_range)
end
...可以使用以下方式调用:
Item.find_by_final_digit_range(2, 9, 12)
...当然,这只是有点疯狂,而且可能有点过分。
答案 1 :(得分:5)
基于欧文的答案:
这是一个非常古老的问题,但是如果有人需要它,有一个非常简单的答案,使用::text
强制转换:
Item.where("(id::text LIKE ?)", "%#{numeric_variable}").all
这样,您可以在字符串中的任何位置找到数字
仅当您希望数字位于字符串末尾时,才在左侧使用%
通配符
如果您希望数字在字符串中的任何位置,也可以使用右侧的%
通配符。
答案 2 :(得分:4)
LIKE
operator仅适用于字符串类型
使用modulo operator %
表示您要执行的操作:
@item = Item.where("(id % 100) = ?", "88").all
我怀疑它在SQLite中“有效”,即使它将数字类型强制转换为字符串。如果没有前导%
,模式将无效
- &GT; sqlfiddle demo
转换为text
并按照您的意图使用LIKE
任意长度:
@item = Item.where("(id::text LIKE ('%'::text || ?)", "'12345'").all
或者,数学上:
@item = Item.where("(id % 10^(length(?)) = ?", "'12345'", "12345").all
答案 3 :(得分:0)
LIKE运算符不适用于数字类型,并且id是数字类型,因此您可以将其与concat一起使用
SELECT * FROM TABLE_NAME WHERE concat("id") LIKE '%ID%'