48

我有一个带有带有数值的字符串列的 Postgres 表。我需要将这些字符串转换为数字进行数学运算,但我需要将两个NULL值以及空字符串解释为0.

我可以将空字符串转换为空值

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

(1 row)

我可以将空值转换为0

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

我可以将字符串转换为数字

# 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

4 回答 4

41

值的类型需要一致;将空字符串合并为 0 意味着您不能将其nullnullif. 所以这些工作中的任何一个:

# 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)
于 2013-09-23T02:27:27.293 回答
15

你也可以使用

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

于 2013-09-23T02:55:20.623 回答
9

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

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

或者

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

参考

于 2013-11-15T09:28:39.573 回答
0

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

SELECT CAST(TO_JSON(NULLIF(:myParameter, NULL)) AS VARCHAR) IS NULL OR
   CAST(TO_JSON(NULLIF(:myParameter, NULL)) AS VARCHAR) IN ('""');
于 2020-01-29T08:52:27.070 回答