У меня была такая же потребность, и я обнаружил, что это хорошо работает для меня (postgres 8.4):
CAST((COALESCE(myfield,'0')) AS INTEGER)
Некоторые тестовые примеры для демонстрации:
db=> select CAST((COALESCE(NULL,'0')) AS INTEGER);
int4
------
0
(1 row)
db=> select CAST((COALESCE('','0')) AS INTEGER);
int4
------
0
(1 row)
db=> select CAST((COALESCE('4','0')) AS INTEGER);
int4
------
4
(1 row)
db=> select CAST((COALESCE('bad','0')) AS INTEGER);
ERROR: invalid input syntax for integer: "bad"
Если вам нужно обработать возможность того, что поле имеет нечисловой текст (например, «100bad»), вы можете использовать regexp_replace для удаления нечисловых символов перед преобразованием.
CAST(REGEXP_REPLACE(COALESCE(myfield,'0'), '[^0-9]+', '', 'g') AS INTEGER)
Тогда значения text / varchar, такие как "b3ad5", также будут давать числа
db=> select CAST(REGEXP_REPLACE(COALESCE('b3ad5','0'), '[^0-9]+', '', 'g') AS INTEGER);
regexp_replace
----------------
35
(1 row)
Чтобы решить проблему Криса Когдона по поводу того, что решение не дает 0 для всех случаев, включая такой случай, как «плохой» (вообще нет цифровых символов), я сделал это скорректированное заявление:
CAST((COALESCE(NULLIF(REGEXP_REPLACE(myfield, '[^0-9]+', '', 'g'), ''), '0')) AS INTEGER);
Он работает аналогично более простым решениям, за исключением того, что он будет давать 0, когда значение для преобразования состоит только из нецифровых символов, например "плохо":
db=> select CAST((COALESCE(NULLIF(REGEXP_REPLACE('no longer bad!', '[^0-9]+', '', 'g'), ''), '0')) AS INTEGER);
coalesce
----------
0
(1 row)