Введите строку в целое число - Postgres
Я импортирую данные из таблицы, которая имеет сырые каналы в Varchar, мне нужно импортировать столбец в Varchar в столбец строки. Я пытался использовать <column_name>::integer
так же как to_number(<column_name>,'9999999')
но я получаю ошибки, так как есть несколько пустых полей, мне нужно извлечь их как пустые или нулевые в новую таблицу.
Пожалуйста, дайте мне знать, если есть функция для того же.
12 ответов
Подсказка: если ваше значение является пустой строкой, вы можете использовать NULLIF, чтобы заменить его на NULL:
SELECT
NULLIF(your_value, '')::int
Вы можете даже пойти еще дальше и ограничить это объединенное поле, например:-
SELECT CAST(coalesce(<column>, '0') AS integer) as new_field
from <table>
where CAST(coalesce(<column>, '0') AS integer) >= 10;
Если вам нужно обработать пустые столбцы как NULL
s, попробуйте это:
SELECT CAST(nullif(<column>, '') AS integer);
С другой стороны, если у вас есть NULL
значения, которых вам нужно избегать, попробуйте:
SELECT CAST(coalesce(<column>, '0') AS integer);
Я согласен, сообщение об ошибке очень поможет.
Единственный способ избежать ошибки из-за NULL, специальных символов или пустой строки - это сделать так:
SELECT REGEXP_REPLACE(COALESCE(<column>, '0'), '[^0-9]*' ,'0')::integer FROM table
Если значение содержит нечисловые символы, вы можете преобразовать значение в целое число следующим образом:
SELECT CASE WHEN <column>~E'^\\d+$' THEN CAST (<column> AS INTEGER) ELSE 0 END FROM table;
Оператор CASE проверяет <столбец>, если он соответствует целочисленному шаблону, он преобразует скорость в целое число, в противном случае он возвращает 0
Я не могу комментировать (слишком мало репутации? Я довольно новый) пост Лукаса.
На моей настройке PG to_number(NULL)
не работает, поэтому мое решение будет:
SELECT CASE WHEN column = NULL THEN NULL ELSE column :: Integer END
FROM table
Общая проблема
Наивно введите преобразование любой строки в целое число вроде этого
SELECT ''::integer
Часто приводит к известной ошибке:
Query failed: ERROR: invalid input syntax for integer: ""
Проблема
В PostgreSQL нет предопределенной функции для безопасного преобразования любой строки в целое число.
Решение
Создайте пользовательскую функцию, вдохновленную функцией PHP intval().
CREATE FUNCTION intval(character varying) RETURNS integer AS $$
SELECT
CASE
WHEN length(btrim(regexp_replace($1, '[^0-9]', '','g')))>0 THEN btrim(regexp_replace($1, '[^0-9]', '','g'))::integer
ELSE 0
END AS intval;
$$
LANGUAGE SQL
IMMUTABLE
RETURNS NULL ON NULL INPUT;
Применение
/* Example 1 */
SELECT intval('9000');
-- output: 9000
/* Example 2 */
SELECT intval('9gag');
-- output: 9
/* Example 3 */
SELECT intval('the quick brown fox jumps over the lazy dog');
-- output: 0
Вы можете использовать этот запрос
SUM(NULLIF(conversion_units, '')::numeric)
Идеальное решение для меня - использовать и
Приведенное выше решение рассматривает следующие крайние случаи.
- Строка и число: только функция отлично конвертирует в целые числа.
SELECT NULLIF(REGEXP_REPLACE('string and 12345', '[^0-9]', '', 'g'), '')::bigint;
- Только строка:
regexp_replace
преобразует нестроковые символы в пустые строки; который не может быть приведен непосредственно к целому числу, поэтому используйтеnullif
преобразовать в ноль
SELECT NULLIF(REGEXP_REPLACE('only string', '[^0-9]', '', 'g'), '')::bigint;
- Целочисленный диапазон: Преобразование строки в целое число может привести к ошибке вне диапазона для целочисленного типа . Так что используйте
bigint
вместо
SELECT NULLIF(REGEXP_REPLACE('98123162t3712t37', '[^0-9]', '', 'g'), '')::bigint;
И если в вашем столбце есть десятичные точки
select NULLIF('105.0', '')::decimal
Мои два цента за приведение любой строки к целому числу:
SELECT REGEXP_REPLACE('0' || "<column>", '[[:alpha:]]', '', 'g')::int
На основе https://www.postgresqltutorial.com/regexp_replace/.
Это работает для меня:
select (left(regexp_replace(coalesce('<column_name>', '0') || '', '[^0-9]', '', 'g'), 8) || '0')::integer
Для удобства просмотра:
select (
left(
regexp_replace(
-- if null then '0', and convert to string for regexp
coalesce('<column_name>', '0') || '',
'[^0-9]',
'',
'g'
), -- remove everything except numbers
8 -- ensure ::integer doesn't overload
) || '0' -- ensure not empty string gets to ::integer
)::integer