Postgresql. Косяк при преобразовании текста в число, Теряются разряды
В таблице есть столбец с идентификаторами вида YYMM.DD№№
2101.1601#
2101.1602#
2101.1701#
т.е. это дата плюс двузначное число. Мне нужно создать новый идентификатор на определённую дату.
Регуляркой выбираю последние 3 цифры из идентификаторов за опред дату напр 16.01.2021
SELECT REGEXP_MATCHES(номСделки, '\d\d\d(?=\D*$)', 'g')
FROM db.Сделки
WHERE номСделки ~ '2101\.16';
получаю набор: ( кстати что значат эти фиг скобки при выводе? )
{601}
{602}
теперь мне нужно изменит их тип на integer.
Пробовал to_number( val, '999' ); Почему то возвращает 60 вместо 601 куда-то девается один разряд.
Если пишу вручную to_number( '601', '999' ); результат правильный,
Если пишу вручную со скобками как в рез выборки to_number( '{601}', '999' );
то опять получаю такой же косяк 60 вместо 601. В чём дело?
Ответы (1 шт):
получаю набор: ( кстати что значат эти фиг скобки при выводе? )
В документации это явно указывается
The regexp_matches function returns a set of text arrays of captured substring(s)
Т.е. эта функция возвращает не первое подходящее значение, а все (даже если оно только одно) в виде массива.
Я бы на твоём месте решал обратную задачу - стереть ненужное
select regexp_replace(regexp_replace('2021.0119687asd', '^\d{4}\.\d{4}', ''), '\D*$', '')
или даже (если ты уверен в длине префикса)
select regexp_replace(substr('2021.0119687asd', 10), '\D*$', '')
Ещё, кстати, совет создать дату в таблице сделок, индекс по этой дате и фильтровать по ней, вместо регулярного выражения, потому что с ростом размера таблицы твой фильтр просто убьёт всю производительность. Ну и прямо сейчас заменить WHERE номСделки ~ '2101\.16'; на WHERE номСделки ~ '^2101\.16';