2013-09-23 184 views
22

我有一個Postgres表格,其中包含一個帶有數字值的字符串列。我需要將這些字符串轉換爲數學數字,但我需要NULL值以及空字符串被解釋爲0將字符串轉換爲數字,將空字符串或空字符串解釋爲0

我可以convert empty strings into null values

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

(1 row) 

,我可以convert null values into a 0

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

,我可以convert strings into numbers

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

但是,當我嘗試將這些技術結合起來,我得到錯誤:

# 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; 

我在做什麼錯?

+3

附註 - 這是更好地在大多數情況下,使用'numeric'而不是'float'。只有當你知道你真的需要'浮動'時才使用'浮動'。 –

回答

22

值的類型需要一致;將空字符串合併爲0意味着您不能將它與nullif中的null進行比較。因此,無論這些作品:

# 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

您也可以使用

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

你也可以打開那一點,因爲你開始相當冗長反正:

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

或者你可以把鑄件放在CASE裏面:

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

CASE使得它更容易解釋任何其他特殊情況,這也似乎是邏輯IMO的更清晰表達。 OTOH,個人品味等等。

3

實際上,您可以將NULL轉換爲int,您不能將空字符串轉換爲int。假設你想在新列NULL,如果數據1包含一個空字符串或NULL,你可以做這樣的事情:

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

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

Reference

+0

從第二句:_「[...]我需要兩個NULL值以及空字符串解釋爲0。」_ – Phrogz