Так что в моем PostgreSQL 10 у меня есть столбец типа integer. Этот столбец представляет код продуктов, и его следует искать в другом коде или части кода. Значения столбца состоят из трех частей, пятизначной части и двух двузначных частей. Пользователи могут искать только первую часть, первую-вторую или первую-вторую-третью.

Итак, в моей колонке, скажем, 123451233 пользователь ищет 12345 (первая часть). Я хочу иметь возможность вернуть 123451233. То же самое происходит, если пользователи также ищут 1234512 или 123451233.

К сожалению, я не могу изменить тип столбца или разбить один столбец на три (по одному для каждой части). Как я могу это сделать? Я не могу использовать LIKE. Может быть, что-то вроде регулярного выражения для целых чисел?

Благодарность

0
slevin 20 Авг 2018 в 17:48

3 ответа

Лучший ответ

Вам не нужны функции регулярных выражений. Приведите целое число к text и используйте функцию {{X1 }}, пример:

create table my_table(code int); -- or bigint
insert into my_table values (123451233);

with input_data(input_code) as (
    values('1234512')
)

select t.*
from my_table t
cross join input_data
where left(code::text, length(input_code)) = input_code;

   code    
-----------
 123451233
(1 row) 
1
klin 20 Авг 2018 в 15:43

Рассмотрим использование простой арифметики. log(value)::int + 1 возвращает количество цифр в целой части value и использует это:

value/(10^(log(value)::int-log(search_input)::int))::int

Возвращает value усеченный до того же номера, что и search_input, и, наконец,

search_input = value/(10^(log(value)::int-log(search_input)::int))::int

Сделает трюк.

Это буквально более сложно, но также может быть более эффективным, чем манипуляции со строками.

PS: Но имеет индекс, подобный create index idx on your_table(cast(your_column as text));, как поиск

select * from your_table
where cast(your_column as text) like search_input || '%';

Это лучший случай ИМО.

1
Abelisto 20 Авг 2018 в 17:55
\b(123)[0-9]+\b

Вышеупомянутое регулярное выражение будет соответствовать с начала строки.

Все, что вам нужно сделать, это поставить поисковый термин в скобках

Пример: regexr.com/3u6ii

Так что \b(123)[0-9]+\b будет соответствовать всему:

 -> 1234567
    1245621
    193602

Но \b(12)[0-9]+\b будет соответствовать как первому, так и второму

1
Tom 20 Авг 2018 в 15:01
51933319