PostgreSQL - 从双精度字段中获取所有整数数字以用于 to_char 函数
PostgreSQL - get all integer digits from double precision field for use in to_char function
如 documentation of Postgres 9.0 所述,double precision
数据类型具有 15 位十进制数字的精度和 8 个字节的存储空间,然后是比正常 bigint
大的整数( 8 个字节)存储在 double precision
字段中是近似的。如果我错了请纠正我,我说的比正常 bigint
大,因为如果您尝试将此数字转换为 bigint
,您会收到此错误:
select 211116514527303268704::bigint;
>> ERROR: bigint out of range
当您尝试将其转换为 double precision
和 numeric
并比较两者时,您会发现它们是相同的:
select 211116514527303268704::numeric,
211116514527303268704::double precision,
(211116514527303268704::double precision) = (211116514527303268704::numeric);
+-----------------------+----------------------+---------+
| numeric | float8 | boolean |
+-----------------------+----------------------+---------+
| 211116514527303268704 | 2.11116514527303e+20 | t |
+-----------------------+----------------------+---------+
并且使用 to_char()
函数,它们 return 不同的值:
select
trim(to_char((211116514527303268704::double precision),'999,999,999,999,999,999,999')),
trim(to_char((211116514527303268704::numeric),'999,999,999,999,999,999,999'));
+-----------------------------+-----------------------------+
| text | text |
+-----------------------------+-----------------------------+
| 211,116,514,527,303,270,400 | 211,116,514,527,303,268,704 |
+-----------------------------+-----------------------------+
如您所见,值 return 使用 to_char 编辑 - 数字组合是正确的,但 to_char - 双精度与 [=14= 中的指数部分失去一致性] 2.11116514527303e+20
我不确定它是否会影响某些东西,但 lc_numeric
的语言环境是 'es_PY.utf8'
在这种情况下实现 double precision
是完全没用的,还是保留那些双精度字段的另一种选择?这始终是首选选项,有某种类型的从 double precision
到 numeric
的转换保留所有原始数字?
有关其他信息,我在 CentOS 6 x86-64 服务器上安装了 PostgreSQL 9.0 运行。
原因是为了进行相等比较,将分辨率较高的类型转换为分辨率较低的类型。即:在示例中 numeric
被转换为 double precision
.
演示:
SELECT *
, num = dp AS no_cast
, num::float8 = dp AS dp_cast
, num = dp::numeric AS num_cast
FROM (
SELECT numeric '211116514527303268705' AS num
, float8 '211116514527303268705' AS dp
) t;
num | dp | no_cast | dp_cast | num_cast
----------------------+-----------------------+---------+---------+---------
211116514527303268705 | 2.11116514527303e+020 | t | t | f
float8
是 double precision
.
的别名
请注意,对于其他计算,如加法,具有 更高 分辨率的类型是结果 - 这是逻辑必需的。 (反正这里的结果是boolean
)
如 documentation of Postgres 9.0 所述,double precision
数据类型具有 15 位十进制数字的精度和 8 个字节的存储空间,然后是比正常 bigint
大的整数( 8 个字节)存储在 double precision
字段中是近似的。如果我错了请纠正我,我说的比正常 bigint
大,因为如果您尝试将此数字转换为 bigint
,您会收到此错误:
select 211116514527303268704::bigint;
>> ERROR: bigint out of range
当您尝试将其转换为 double precision
和 numeric
并比较两者时,您会发现它们是相同的:
select 211116514527303268704::numeric,
211116514527303268704::double precision,
(211116514527303268704::double precision) = (211116514527303268704::numeric);
+-----------------------+----------------------+---------+
| numeric | float8 | boolean |
+-----------------------+----------------------+---------+
| 211116514527303268704 | 2.11116514527303e+20 | t |
+-----------------------+----------------------+---------+
并且使用 to_char()
函数,它们 return 不同的值:
select
trim(to_char((211116514527303268704::double precision),'999,999,999,999,999,999,999')),
trim(to_char((211116514527303268704::numeric),'999,999,999,999,999,999,999'));
+-----------------------------+-----------------------------+
| text | text |
+-----------------------------+-----------------------------+
| 211,116,514,527,303,270,400 | 211,116,514,527,303,268,704 |
+-----------------------------+-----------------------------+
如您所见,值 return 使用 to_char 编辑 - 数字组合是正确的,但 to_char - 双精度与 [=14= 中的指数部分失去一致性] 2.11116514527303e+20
我不确定它是否会影响某些东西,但 lc_numeric
的语言环境是 'es_PY.utf8'
在这种情况下实现 double precision
是完全没用的,还是保留那些双精度字段的另一种选择?这始终是首选选项,有某种类型的从 double precision
到 numeric
的转换保留所有原始数字?
有关其他信息,我在 CentOS 6 x86-64 服务器上安装了 PostgreSQL 9.0 运行。
原因是为了进行相等比较,将分辨率较高的类型转换为分辨率较低的类型。即:在示例中 numeric
被转换为 double precision
.
演示:
SELECT *
, num = dp AS no_cast
, num::float8 = dp AS dp_cast
, num = dp::numeric AS num_cast
FROM (
SELECT numeric '211116514527303268705' AS num
, float8 '211116514527303268705' AS dp
) t;
num | dp | no_cast | dp_cast | num_cast
----------------------+-----------------------+---------+---------+---------
211116514527303268705 | 2.11116514527303e+020 | t | t | f
float8
是 double precision
.
的别名
请注意,对于其他计算,如加法,具有 更高 分辨率的类型是结果 - 这是逻辑必需的。 (反正这里的结果是boolean
)