Miałem taką samą potrzebę i stwierdziłem, że działa to dobrze dla mnie (postgres 8.4):
CAST((COALESCE(myfield,'0')) AS INTEGER)
Niektóre przypadki testowe do zademonstrowania:
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"
Jeśli chcesz poradzić sobie z możliwością, że pole ma tekst nienumeryczny (na przykład „100bad”), możesz użyć regexp_replace, aby usunąć znaki nienumeryczne przed rzutowaniem.
CAST(REGEXP_REPLACE(COALESCE(myfield,'0'), '[^0-9]+', '', 'g') AS INTEGER)
Wtedy wartości text / varchar, takie jak „b3ad5”, również będą zawierać liczby
db=> select CAST(REGEXP_REPLACE(COALESCE('b3ad5','0'), '[^0-9]+', '', 'g') AS INTEGER);
regexp_replace
35
(1 row)
Aby rozwiązać obawę Chrisa Cogdona dotyczącą rozwiązania, które nie daje 0 dla wszystkich przypadków, w tym przypadku takiego jak „zły” (w ogóle bez znaków cyfrowych), poczyniłem to skorygowane stwierdzenie:
CAST((COALESCE(NULLIF(REGEXP_REPLACE(myfield, '[^0-9]+', '', 'g'), ''), '0')) AS INTEGER);
Działa podobnie do prostszych rozwiązań, z tą różnicą, że daje 0, gdy wartość do konwersji zawiera tylko znaki niecyfrowe, na przykład „zła”:
db=> select CAST((COALESCE(NULLIF(REGEXP_REPLACE('no longer bad!', '[^0-9]+', '', 'g'), ''), '0')) AS INTEGER);
coalesce
0
(1 row)