【问题标题】:Cast string to number, interpreting null or empty string as 0将字符串转换为数字,将 null 或空字符串解释为 0
【发布时间】:2013-09-27 20:37:38
【问题描述】:

我有一个 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;

我做错了什么?

【问题讨论】:

  • 旁注 - 在大多数情况下,最好使用numeric 而不是float。只有当你知道你真的需要float时才使用float

标签: sql postgresql syntax


【解决方案1】:

你也可以使用

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】:

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

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

    【讨论】:

      【解决方案3】:

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

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

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

      Reference

      【讨论】:

      • 从第二句开始:"[…] 我需要将 NULL 值和空字符串都解释为 0。"
      【解决方案4】:

      值的类型需要一致;将空字符串合并为 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)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-05-18
        • 2022-01-08
        • 2020-06-20
        • 1970-01-01
        • 2012-04-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多