将字符串转换为数字,将null或空字符串解释为0

时间:2013-09-23 02:27:27

标签: sql postgresql syntax

我有一个带有数字值字符串列的Postgres表。我需要将这些字符串转换为数字的数字,但我需要将NULL值和空字符串都解释为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;

我做错了什么?

4 个答案:

答案 0 :(得分:30)

值的类型必须一致;将空字符串合并为0意味着您无法将其与null中的nullif进行比较。所以这些都有效:

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

答案 1 :(得分:8)

您也可以使用

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,个人品味等等。

答案 2 :(得分:5)

实际上,你可以将NULL转换为int,你只是不能将空字符串转换为int。假设如果data1包含空字符串或NULL,则在新列中需要NULL,您可以执行以下操作:

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

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

Reference

答案 3 :(得分:0)

检查查询参数是否为空(接受null,空字符串或值):

SELECT CAST(TO_JSON(NULLIF(:myParameter, NULL)) AS VARCHAR) IS NULL OR
   CAST(TO_JSON(NULLIF(:myParameter, NULL)) AS VARCHAR) IN ('""');