如何在PostgreSQL主id列上执行LIKE查询?

时间:2012-11-30 23:28:33

标签: sql ruby-on-rails ruby postgresql activerecord

如果我有一个数字(例如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

我该怎么做?我已经尝试将数字转换为字符串,但这似乎也不起作用。

4 个答案:

答案 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)

匹配任意长度

的最终数字范围

假设您想要查找以 id09之间的数字结尾的所有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是数字类型,因此您可以将其与c​​oncat一起使用

SELECT * FROM TABLE_NAME WHERE concat("id") LIKE '%ID%'