Avevo lo stesso tipo di necessità e ho trovato che funzionava bene per me (Postgres 8.4):
CAST((COALESCE(myfield,'0')) AS INTEGER)
Alcuni casi di test per dimostrare:
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"
Se è necessario gestire la possibilità che il campo contenga testo non numerico (come "100bad"), è possibile utilizzare regexp_replace per rimuovere i caratteri non numerici prima del cast.
CAST(REGEXP_REPLACE(COALESCE(myfield,'0'), '[^0-9]+', '', 'g') AS INTEGER)
Quindi anche valori text / varchar come "b3ad5" forniranno numeri
db=> select CAST(REGEXP_REPLACE(COALESCE('b3ad5','0'), '[^0-9]+', '', 'g') AS INTEGER);
regexp_replace
----------------
35
(1 row)
Per rispondere alla preoccupazione di Chris Cogdon con la soluzione che non fornisce 0 per tutti i casi, incluso un caso come "cattivo" (nessun carattere di cifre), ho fatto questa dichiarazione modificata:
CAST((COALESCE(NULLIF(REGEXP_REPLACE(myfield, '[^0-9]+', '', 'g'), ''), '0')) AS INTEGER);
Funziona in modo simile alle soluzioni più semplici, tranne che fornirà 0 quando il valore da convertire è solo caratteri non numerici, come "cattivo":
db=> select CAST((COALESCE(NULLIF(REGEXP_REPLACE('no longer bad!', '[^0-9]+', '', 'g'), ''), '0')) AS INTEGER);
coalesce
----------
0
(1 row)