0

我正在研究将输入值与存储记录进行比较的搜索部分。数据库具有像 AB 09 CD 1234 这样的值。我已经爆炸(带空格)输入字符串以匹配存储的值,但是当我给出像 AB09 CD 1234 这样的输入时,它不会产生高于记录的结果。

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

db 中的车辆编号: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 的第四个参数。

4

3 回答 3

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无法使用任何索引,因为模式以 开头%。)

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

于 2013-04-01T11:58:28.620 回答
1

如果您想将索引与@cdhowie 提供的查询类似(如果这是对大表的常见查询,您应该使用该查询),请使用附加模块pg_trgm提供的功能三元索引:

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 的相关答案:
有效地查询包含子字符串的列
dba.SE 上的这个。

于 2013-04-01T13:04:31.097 回答
0

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

SELECT * FROM some_vehicle WHERE vehicle_number ILIKE E\'%A%B%0%9%C%D%1%2%3%4%'
于 2013-04-01T11:57:53.930 回答