Ich hatte das gleiche Bedürfnis und fand, dass dies für mich gut funktioniert (postgres 8.4):
CAST((COALESCE(myfield,'0')) AS INTEGER)
Einige Testfälle zur Demonstration:
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"
Wenn Sie die Möglichkeit behandeln müssen, dass das Feld nicht numerischen Text enthält (z. B. "100bad"), können Sie mit regexp_replace nicht numerische Zeichen vor der Umwandlung entfernen.
CAST(REGEXP_REPLACE(COALESCE(myfield,'0'), '[^0-9]+', '', 'g') AS INTEGER)
Dann geben Text- / Varchar-Werte wie "b3ad5" auch Zahlen an
db=> select CAST(REGEXP_REPLACE(COALESCE('b3ad5','0'), '[^0-9]+', '', 'g') AS INTEGER);
regexp_replace
----------------
35
(1 row)
Um Chris Cogdons Besorgnis über die Lösung anzusprechen, die nicht für alle Fälle 0 ergibt, einschließlich eines Falls wie "schlecht" (überhaupt keine Ziffern), habe ich diese angepasste Aussage gemacht:
CAST((COALESCE(NULLIF(REGEXP_REPLACE(myfield, '[^0-9]+', '', 'g'), ''), '0')) AS INTEGER);
Es funktioniert ähnlich wie die einfacheren Lösungen, außer dass 0 angegeben wird, wenn der zu konvertierende Wert nur aus nichtstelligen Zeichen besteht, z. B. "schlecht":
db=> select CAST((COALESCE(NULLIF(REGEXP_REPLACE('no longer bad!', '[^0-9]+', '', 'g'), ''), '0')) AS INTEGER);
coalesce
----------
0
(1 row)