Все значения начинаются с символа или числа и заканчиваются либо цифрой, символом или специальным символом.... В значении есть специальные символы, такие как ,.()&/
.
Я предлагаю оператор совпадения с регулярным выражением ~ .Тщательно определите границы и экранирующие специальные символы в name
:
Создать один раз :
CREATE OR REPLACE FUNCTION f_regexp_escape(text)
RETURNS text AS
$func$
SELECT regexp_replace($1, '([!$()*+.:<=>?[\\\]^{|}-])', '\\\1', 'g')
$func$ LANGUAGE sql IMMUTABLE;
Тогда:
SELECT * FROM manufacturer
WHERE '3dad QTICE EEN ' ~ ('\m' || f_regexp_escape(name) || '( |$)')
Как?Почему?
\m
.. начало слова. Работает, так как: значения начинаются с символа или цифры
( |$)
.. aпробел или конец строки.Нам это нужно, поскольку значения: оканчиваются цифрой, символом или специальным символом
Содержимое manufacturer.name
является ядром шаблона .Вы хотите буквальное значение всех его символов, поэтому уберите любое специальное значение, избегая правильно.Это верно для LIKE
(несколько специальных символов), а также для оператора совпадения с регулярным выражением ~
(больше специальных символов).Часто упускается из виду и довольно ловушка.Это дало вам (и хитрое определение границ).Прочитайте это!
А затем используйте функцию f_regexp_escape()
, как показано.A name
like:
3M (UNITY) USA. INC.
становится:
3M \(UNITY\) USA\. INC\.
Может быть удобно хранить легко экранированные шаблоны в таблице manufacturer
, возможно, в качестве дополнительного столбца.И, возможно, с дополнительным заполнением, как это:
\m3M \(UNITY\) USA\. INC\.( |$)
Или создайте шаблон на лету, как показано.
Таким образом name
может быть одним словом или целой фразой, и конецс любыми персонажами.Но начало и конец никогда не совпадают в середине «слова» на другой стороне.
В Postgres есть арсенал других инструментов сопоставления с образцом:
Если ваша таблица большая, рассмотрим полнотекстовый поиск инфраструктура с оптимизированными индексами и поиск по фразе возможность: