如何防止 PostgreSQL 舍入双精度值的输出?

How to prevent PostgreSQL from rounding the output of double precision values?

我有一个 table 个位置,其中包含来自多个提供商的相关数据。我将提供商 ID、纬度和经度(两个坐标均为 double precision)作为主键。但是现在,我想从提供者生成一个varchar(50)类型的id,纬度和经度(两个坐标都是双精度值):

UPDATE mytable 
   SET id = CONCAT(provider, '-', latitude, '-', longitude)

但是当我尝试将新列设置为主键时

ALTER TABLE mytable ADD PRIMARY KEY (id)

我收到错误

Key (id)=(2-53.69706-12.71236) is duplicated.

原来id='2-53.69706-12.71236'确实有两个条目,但只有其中一个的经度为12.71236。另一个经度为 12.71235999999999。虽然我可以通过这些不同的经度 select 它们:

SELECT
    longitude,
    to_char(longitude, '999D9999999999999999') AS longitude_to_char,
    data->>'ID' AS id_within_provider
FROM mytable
WHERE provider=2 AND latitude=53.69706 AND longitude=12.71236
longitude | longitude_to_char  | id_within_provider
 12.71236 |   12.7123600000000 | 42266
SELECT
    longitude,
    to_char(longitude, '999D9999999999999999') AS longitude_to_char,
    data->>'ID' AS id_within_provider
FROM mytable
WHERE provider=2 AND latitude=53.69706 AND longitude=12.71235999999999
longitude | longitude_to_char  | id_within_provider 
 12.71236 |   12.7123600000000 | 84742

即使我尝试以明确的精度将其转换为 char,输出经度也保持不变。有趣的是,to_char(12.71235999999999, '999D9999999999999999') 产生原始数字,而 to_char(longitude, '999D9999999999999999') 总是产生四舍五入的数字。

所以我有两个不同的双精度值,我无法以不同的方式输出它们应该如何输出。我能做些什么?我做错了什么吗?

尝试将双精度值格式化为唯一的 varchar 值几乎是不可能的。简而言之,你正在打一场必败仗。

这里明确的解决方案是使用复合主键:

ALTER TABLE mytable ADD PRIMARY KEY (provider, latitude, longitude)

或者,您可以使用 SERIAL 列作为主键,并向这些列添加唯一约束(虽然我不明白为什么)。