列出PostgreSQL中的匹配记录

时间:2013-04-01 11:55:24

标签: php sql postgresql indexing pattern-matching

我正在研究将输入值与存储记录进行比较的搜索部分。数据库的值类似于AB 09 C D 1234.我爆炸(带空格)输入字符串与存储值匹配但是当我输入像AB09 CD 1234这样的输入时,它不会产生上述记录。

SELECT * FROM some_vehicle WHERE vehicle_number ILIKE E\'%AB09 CD 1234%' 
db中的

vehicle_number:AB 09 C D 1234
输入字符串:AB09 CD 1234

我希望结果输入字符串的所有可能情况。在PostgreSQL中有没有办法做到这一点?

“替换”功能可以消除字符串中的空白区域。在PostgreSQL中是否有任何方法可以消除所有特殊字符以及空格。我正在尝试不同的正则表达式,如

regexp_replace(vehicle_number,'[^ a-z0-9 \ s]','')和 regexp_replace(vehicle_number,'[(| - |)| \:| \ @ |#| \ $ | * |。|!| \,]','') 但它不起作用。

由于

几次尝试后想出来!非常接近它。 “[^ a-zA-Z0-9]”模式消除所有特殊字符,包括带有'g'选项的空格作为PostgreSQL中regexp_replace的第四个参数。

3 个答案:

答案 0 :(得分:2)

您可以执行以下操作,从两个值中删除所有空格:

SELECT * FROM some_vehicle
WHERE replace(lower(vehicle_number), ' ', '') =
      replace(lower('AB09 CD 1234'), ' ', '');

或者,如果你想保留子串匹配:

SELECT * FROM some_vehicle
WHERE replace(lower(vehicle_number), ' ', '') LIKE
      ('%' || replace(lower('AB09 CD 1234'), ' ', '') || '%');

请注意,这将无法使用您vehicle_number上当前拥有的任何索引,并且导致seq扫描(或者如果您幸运,可能会进行索引扫描),除非您可以创建专门的表达式索引来有效地处理此查询:

CREATE INDEX ON some_vehicle (( replace(lower(vehicle_number), ' ', '') ));

(使用LIKE的子字符串查询将为unable to use any index,因为模式以%开头。)

另一种选择,如果您的vehicle_number值在完全相同的位置始终有空格,则存储这些值不带空格,并在显示层(或视图)中插入空格,因为您确切知道它们的位置将会是。然后,您可以简单地从任何搜索值中删除空格。

答案 1 :(得分:1)

如果要使用带有provided by @cdhowie之类的查询的索引(如果这是大表上的常见查询,则应使用该索引),请使用附加模块提供的功能性三元组索引{{ 3}}:

CREATE EXTENSION pg_trgm; -- once per database

CREATE INDEX some_name_idx ON some_vehicle
USING GIN (replace(vehicle_number, ' ', '')  gin_trgm_ops);

我没有使用lower(),因为这不是您问题中的问题。匹配的查询将是:

SELECT * FROM some_vehicle
WHERE replace(vehicle_number, ' ', '')
      LIKE ('%' || replace('AB09 CD 1234', ' ', '') ||  '%');

关于SO的相关答案:
pg_trgm
Effectively query on column that includes a substring

答案 2 :(得分:0)

如果你的意思是空间的组合,那么:

SELECT * FROM some_vehicle WHERE vehicle_number ILIKE E\'%A%B%0%9%C%D%1%2%3%4%'