2016-05-05 7 views
0

Ich habe festgestellt, dass Amazon Redshift die Genauigkeit von Fließkommazahlen auf eine sehr niedrige Genauigkeit (6 Stellen) verkürzt. Gibt es einen Weg dazu?Warum schneidet Amazon Redshift die Genauigkeit dieser JSON-Floatdaten ab?

Beispiel:

SELECT 
JSON_EXTRACT_PATH_TEXT('{"a":123456789.5555555, "b":123456789.0}', 'a')::float, 
JSON_EXTRACT_PATH_TEXT('{"a":123456789.5555555, "b":123456789.0}', 'b')::float; 

Gibt:

json_extract_path_text | json_extract_path_text 
------------------------+------------------------ 
       123457000 |    123457000 
(1 row) 

Vergleichen Sie das mit ganzen Zahlen:

SELECT 
JSON_EXTRACT_PATH_TEXT('{"a":123456789, "b":123456789}', 'a')::float, 
JSON_EXTRACT_PATH_TEXT('{"a":123456789, "b":123456789}', 'b')::float; 

was zur Folge hat:

json_extract_path_text | json_extract_path_text 
------------------------+------------------------ 
       123456789 |    123456789 
(1 row) 

Es scheint, als ob Float mehr Präzision haben sollte, nicht weniger !!!

Danke für jede Einsicht.

+0

Warum brauchen Sie eine solche Genauigkeit in einer analytischen Datenbank? Auf jeden Fall werden Sie AVG und andere statistische Funktionen ausführen, die keine so hohe Genauigkeit benötigen. – Guy

Antwort

0

Das Problem ist nicht die FLOAT-Genauigkeit von Redshift selbst, sondern die Genauigkeit der geparsten JSON-Nummer. Wenn wir abfragen, um die JSON ohne jegliche Konvertierung ...

SELECT JSON_EXTRACT_PATH_TEXT('{"a":123456789.5555555}', 'a'); 

..., die in diesem VARCHAR-Wert ergibt:

"1.23457e+08" 

Daher ist jede nachfolgende Umwandlung in FLOAT nur mit diesem bereits ungenauen Wert arbeiten kann.

Eine Abhilfe, die Zahlen innerhalb der JSON als Zeichenfolge zu speichern wäre ...

SELECT JSON_EXTRACT_PATH_TEXT('{"a":"123456789.5555555"}', 'a')::float; 
↓ 
123456789.55555549 

Wenn noch höhere Genauigkeit erforderlich ist, eine Umstellung auf den DECIMAL Datentyp verwendet werden könnte ...

SELECT JSON_EXTRACT_PATH_TEXT('{"a":"123456789.5555555", "b":123456789.0}', 'a')::decimal(20, 10) 
↓ 
123456789.5555555000 

Alternativ könnten Sie auch eine User-Defined Function implementieren, wo Sie die JSON-Parsing selbst mit höherer Präzision tun.

Verwandte Themen