2013-09-23 121 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