J'avais le même type de besoin et j'ai trouvé que cela fonctionnait bien pour moi (postgres 8.4):
CAST((COALESCE(myfield,'0')) AS INTEGER)
Quelques cas de test pour démontrer:
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"
Si vous devez gérer la possibilité que le champ contienne du texte non numérique (tel que "100bad"), vous pouvez utiliser regexp_replace pour supprimer les caractères non numériques avant le cast.
CAST(REGEXP_REPLACE(COALESCE(myfield,'0'), '[^0-9]+', '', 'g') AS INTEGER)
Ensuite, les valeurs text / varchar comme "b3ad5" donneront également des nombres
db=> select CAST(REGEXP_REPLACE(COALESCE('b3ad5','0'), '[^0-9]+', '', 'g') AS INTEGER);
regexp_replace
----------------
35
(1 row)
Pour répondre à la préoccupation de Chris Cogdon avec la solution ne donnant pas 0 pour tous les cas, y compris un cas tel que «mauvais» (aucun caractère numérique du tout), j'ai fait cette déclaration ajustée:
CAST((COALESCE(NULLIF(REGEXP_REPLACE(myfield, '[^0-9]+', '', 'g'), ''), '0')) AS INTEGER);
Cela fonctionne de la même manière que les solutions les plus simples, sauf qu'il donnera 0 lorsque la valeur à convertir est uniquement des caractères non numériques, tels que "mauvais":
db=> select CAST((COALESCE(NULLIF(REGEXP_REPLACE('no longer bad!', '[^0-9]+', '', 'g'), ''), '0')) AS INTEGER);
coalesce
----------
0
(1 row)