Tôi có cùng loại nhu cầu và thấy điều này hoạt động tốt với tôi (postgres 8.4):
CAST((COALESCE(myfield,'0')) AS INTEGER)
Một số trường hợp thử nghiệm để chứng minh:
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"
Nếu bạn cần xử lý khả năng trường có văn bản không phải là số (chẳng hạn như "100bad"), bạn có thể sử dụng biểu thức chính quy để loại bỏ các ký tự không phải là số trước khi truyền.
CAST(REGEXP_REPLACE(COALESCE(myfield,'0'), '[^0-9]+', '', 'g') AS INTEGER)
Sau đó, các giá trị văn bản / varchar như "b3ad5" cũng sẽ đưa ra số
db=> select CAST(REGEXP_REPLACE(COALESCE('b3ad5','0'), '[^0-9]+', '', 'g') AS INTEGER);
regexp_replace
----------------
35
(1 row)
Để giải quyết mối quan tâm của Chris Cogdon với giải pháp không đưa ra 0 cho tất cả các trường hợp, bao gồm cả trường hợp như "xấu" (không có ký tự chữ số nào), tôi đã đưa ra tuyên bố điều chỉnh này:
CAST((COALESCE(NULLIF(REGEXP_REPLACE(myfield, '[^0-9]+', '', 'g'), ''), '0')) AS INTEGER);
Nó hoạt động tương tự như các giải pháp đơn giản hơn, ngoại trừ sẽ cho 0 khi giá trị cần chuyển đổi chỉ là các ký tự không có chữ số, chẳng hạn như "xấu":
db=> select CAST((COALESCE(NULLIF(REGEXP_REPLACE('no longer bad!', '[^0-9]+', '', 'g'), ''), '0')) AS INTEGER);
coalesce
----------
0
(1 row)