2013-09-23 5 views
22

Ich habe eine Postgres-Tabelle mit einer Zeichenfolge Spalte mit numerischen Werten. Ich muss diese Zeichenfolgen in Zahlen für Mathematik konvertieren, aber ich brauche sowohl NULL Werte als auch leere Zeichenfolgen als 0 interpretiert werden.Cast-String zu Nummer, Null oder leere Zeichenfolge als 0 interpretiert

Ich kann convert empty strings into null values:

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

(1 row) 

Und ich kann convert null values into a 0:

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

Und ich kann convert strings into numbers:

# select cast('3' as float); 
float8 
-------- 
     3 
(1 row) 

Aber wenn ich versuche, diese Techniken zu kombinieren, ich Fehler:

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

Was mache ich falsch?

+3

Randnotiz - es ist besser, Verwenden Sie in den meisten Fällen 'numerisch' anstelle von' float'. Verwenden Sie 'float' nur, wenn Sie wissen, dass Sie' float' wirklich brauchen. –

Antwort

22

Die Arten von Werten müssen konsistent sein; Wenn Sie den leeren String mit 0 verbinden, können Sie ihn nicht mit null im nullif vergleichen. Also entweder dieser Werke:

# 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

könnten Sie auch

cast(
    case 
     when coalesce(orig, '') = '' then '0' 
     else orig 
    end 
    as float 
) 

Sie könnten auch auspacken verwenden, dass ein bisschen, da Sie beginnen sind ziemlich ausführliche trotzdem:

cast(
    case 
     when orig is null then '0' 
     when orig = '' then '0' 
     else orig 
    end 
    as float 
) 

oder Sie könnten Legen Sie den Guss in das Gehäuse:

case 
    when coalesce(orig, '') = '' then 0.0 
    else cast(orig as float) 
end 

Ein CASE macht es etwas einfacher, andere spezielle Bedingungen zu berücksichtigen, dies scheint auch ein klarer Ausdruck der logischen IMO zu sein. OTOH, persönlicher Geschmack und all das.

3

Eigentlich können Sie NULL nach int umwandeln, Sie können eine leere Zeichenfolge nicht direkt in int umwandeln. Vorausgesetzt, dass Sie in der neuen Spalte NULL wollen, wenn data1 enthält einen leeren String oder NULL, können Sie etwas tun:

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

oder

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

Reference

+0

Aus dem zweiten Satz: _ "[...] Ich brauche sowohl NULL-Werte als auch leere Zeichenfolgen als 0 zu interpretieren." _ – Phrogz

Verwandte Themen