我正在研究将输入值与存储记录进行比较的搜索部分。数据库的值类似于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的第四个参数。
答案 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%'