2013-09-23 30 views
22

Tôi có bảng Postgres với cột chuỗi mang giá trị số. Tôi cần phải chuyển đổi các chuỗi này thành các con số cho toán học, nhưng tôi cần cả hai giá trị NULL cũng như các chuỗi trống cần được hiểu là 0.Chuỗi ký tự thành số, diễn giải chuỗi rỗng hoặc trống là 0

tôi có thể convert empty strings into null values:

# select nullif('',''); 
nullif 
-------- 

(1 row) 

Và tôi có thể convert null values into a 0:

# select coalesce(NULL,0); 
coalesce 
---------- 
     0 
(1 row) 

Và tôi có thể convert strings into numbers:

# select cast('3' as float); 
float8 
-------- 
     3 
(1 row) 

Nhưng khi tôi cố gắng để kết hợp những kỹ thuật này, tôi nhận được lỗi:

# select cast(nullif(coalesce('',0), '') as float); 
ERROR: invalid input syntax for integer: "" 
LINE 1: select cast(nullif(coalesce('',0), '') as float); 

# select coalesce(nullif('3',''),4) as hi; 
ERROR: COALESCE types text and integer cannot be matched 
LINE 1: select coalesce(nullif('3',''),4) as hi; 

Tôi đang làm gì sai?

+3

Side lưu ý - đó là tốt hơn để sử dụng 'số' thay vì' float' trong hầu hết các trường hợp. Sử dụng 'float' chỉ khi bạn biết bạn thực sự cần' float'. –

Trả lời

22

Các loại giá trị cần nhất quán; hợp nhất chuỗi rỗng thành 0 có nghĩa là bạn không thể so sánh chuỗi đó với số null trong số nullif. Vì vậy, một trong những tác phẩm này:

# create table tests (orig varchar); 
CREATE TABLE 

# insert into tests (orig) values ('1'), (''), (NULL), ('0'); 
INSERT 0 4 


# select orig, cast(coalesce(nullif(orig,''),'0') as float) as result from tests; 
orig | result 
------+-------- 
    1 |  1 
     |  0 
     |  0 
    0 |  0 
(4 rows) 


# select orig, coalesce(cast(nullif(orig,'') as float),0) as result from tests; 
orig | result 
------+-------- 
1 |  1 
     |  0 
     |  0 
0 |  0 
(4 rows) 
6

Bạn cũng có thể sử dụng

cast(
    case 
     when coalesce(orig, '') = '' then '0' 
     else orig 
    end 
    as float 
) 

Bạn cũng có thể unwrap rằng một chút kể từ khi bạn bắt đầu khá dài dòng anyway:

cast(
    case 
     when orig is null then '0' 
     when orig = '' then '0' 
     else orig 
    end 
    as float 
) 

hoặc bạn có thể đặt dàn diễn viên bên trong CASE:

case 
    when coalesce(orig, '') = '' then 0.0 
    else cast(orig as float) 
end 

Một TRƯỜNG HỢP làm cho nó dễ dàng hơn một chút để giải thích cho bất kỳ điều kiện đặc biệt nào khác, điều này cũng có vẻ như một biểu hiện rõ ràng hơn về logic IMO. OTOH, sở thích cá nhân và mọi thứ.

3

Thực ra, bạn có thể gán NULL thành int, bạn không thể truyền một chuỗi rỗng vào int. Giả sử bạn muốn NULL ở cột mới nếu data1 chứa một chuỗi rỗng hoặc NULL, bạn có thể làm một cái gì đó như thế này:

UPDATE table SET data2 = cast(nullif(data1, '') AS int); 

hoặc

UPDATE table SET data2 = nullif(data1, '')::int; 

Reference

+0

Từ câu thứ hai: _ "[…] Tôi cần cả hai giá trị NULL cũng như các chuỗi rỗng được hiểu là 0." _ – Phrogz

Các vấn đề liên quan