为啥 Amazon Redshift 会截断此 JSON 浮点数据的精度?
Posted
技术标签:
【中文标题】为啥 Amazon Redshift 会截断此 JSON 浮点数据的精度?【英文标题】:Why is Amazon Redshift truncating the precision of this JSON float data?为什么 Amazon Redshift 会截断此 JSON 浮点数据的精度? 【发布时间】:2016-05-05 22:58:35 【问题描述】:我发现 Amazon Redshift 将浮点数的精度截断为非常低的精度(6 位)。有没有办法解决这个问题?
例子:
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;
给予:
json_extract_path_text | json_extract_path_text
------------------------+------------------------
123457000 | 123457000
(1 row)
将其与整数进行比较:
SELECT
JSON_EXTRACT_PATH_TEXT('"a":123456789, "b":123456789', 'a')::float,
JSON_EXTRACT_PATH_TEXT('"a":123456789, "b":123456789', 'b')::float;
结果:
json_extract_path_text | json_extract_path_text
------------------------+------------------------
123456789 | 123456789
(1 row)
看起来float应该有更高的精度,而不是更少!!!
感谢您的任何见解。
【问题讨论】:
为什么分析数据库需要如此精确?无论如何,您将要做 AVG 和其他不需要如此高精度的统计函数。 【参考方案1】:问题不是 Redshift 本身的 FLOAT 精度,而是解析出来的 JSON 数的精度。如果我们在不进行任何转换的情况下查询 JSON……
SELECT JSON_EXTRACT_PATH_TEXT('"a":123456789.5555555', 'a');
…导致这个 VARCHAR 值:
"1.23457e+08"
因此,任何后续到 FLOAT 的转换只能使用这个已经不准确的值。
一种解决方法是将 JSON 中的数字存储为字符串……
SELECT JSON_EXTRACT_PATH_TEXT('"a":"123456789.5555555"', 'a')::float;
↓
123456789.55555549
如果需要更高的精度,可以使用到DECIMAL 数据类型的转换...
SELECT JSON_EXTRACT_PATH_TEXT('"a":"123456789.5555555", "b":123456789.0', 'a')::decimal(20, 10)
↓
123456789.5555555000
或者,您也可以实现 User-Defined Function,您可以在其中以更高的精度自行解析 JSON。
【讨论】:
以上是关于为啥 Amazon Redshift 会截断此 JSON 浮点数据的精度?的主要内容,如果未能解决你的问题,请参考以下文章
无法使用 SQL Workbench/J 在 Amazon Redshift 中创建新用户
AWS:将日志从 Amazon CloudWatch 导出到 Amazon Redshift
将数据从 Amazon S3 复制到 Redshift 并避免重复行