2013-09-23 9 views
22

Ho una tabella Postgres con una colonna di stringa che trasporta valori numerici. Ho bisogno di convertire queste stringhe in numeri per la matematica, ma ho bisogno sia dei valori NULL sia delle stringhe vuote da interpretare come 0.Cast stringa su numero, interpretazione stringa vuota o vuota come 0

posso convert empty strings into null values:

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

(1 row) 

e posso convert null values into a 0:

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

e posso convert strings into numbers:

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

Ma quando cerco di combinare queste tecniche, ottengo errori:

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

Cosa sto sbagliando?

+3

Nota a margine - è meglio usa 'numeric' invece di' float' nella maggior parte dei casi. Usa 'float' solo quando sai che hai davvero bisogno di' float'. –

risposta

22

I tipi di valori devono essere coerenti; associando la stringa vuota a 0 significa che non è possibile quindi confrontarlo con null nello nullif. Quindi, o di queste opere:

# 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

Si potrebbe anche usare

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

Si potrebbe anche scartare che un po 'dal momento che siete cominciare abbastanza verbose in ogni caso:

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

o si può inserire il cast all'interno del CASE:

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

A CASE rende un po 'più semplice tenere conto di altre condizioni speciali, anche questo sembra un'espressione più chiara della logica IMO. OTOH, gusto personale e tutto il resto.

3

In realtà, è possibile eseguire il cast NULL su int, non è possibile eseguire il cast di una stringa vuota su int. Supponendo che si desidera NULL nella nuova colonna se dati 1 contiene una stringa vuota o NULL, si può fare qualcosa di simile:

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

o

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

Reference

+0

Dalla seconda frase: _ "[...] Ho bisogno sia di valori NULL che di stringhe vuote da interpretare come 0." _ – Phrogz