web-dev-qa-db-ja.com

文字列を数値にキャストし、nullまたは空の文字列を0として解釈します

数値を保持する文字列列を持つPostgresテーブルがあります。これらの文字列を数学用の数値に変換する必要がありますが、NULL値と0として解釈される空の文字列の両方が必要です。

空の文字列をnull値に変換する

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

(1 row)

そして、私は null値を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;

私は何を間違えていますか?

29
Phrogz

値のタイプは一貫している必要があります。空の文字列を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)
34
Phrogz

また使用することができます

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のより明確な表現のようにも見えます。オートー、個人的な好みなどすべて。

8
mu is too short

実際には、NULLをintにキャストできますが、空の文字列をintにキャストすることはできません。 data1に空の文字列またはNULLが含まれている場合、新しい列にNULLが必要であると仮定すると、次のようなことができます。

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

または

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

参照

5