假设我的2
值为NUMERIC
。我想将0.0001
添加到此2
以获取2.0001
。如果我已2.01
,我想向其添加0.000001
以获取2.010001
。
基本上,我想添加一个比数字最后一位(最高精度数字)小4个数量的数字。
对于2.000
的奇怪情况,我可以获得2.0001
或2.0000001
。
我考虑过是否有某种方法可以使用PostgreSQL数据类型函数来提取这些信息,但我找不到任何方法。
我也试着考虑一些计算它的数学方法。我考虑了log
,但这会向我提供有关最高数量级数字的信息,而不是最低数字。
这是信息性的。我只是提供,因为如果我看到其他人提出这个问题,我的第一个想法是,"他们想要做什么?"
我完全清楚这是一个非常奇怪的用例。我面临的问题是,由于一些奇怪的精确问题,我经常通过PostGIS从GEOS收到TopologyException
。 (这与我的输入数据不是特别干净有关。不幸的是,我处理大量数据并且"检测并手动修复问题几何图形"不是一种选择。)值I处理有效的是容差参数。它被送入缓冲区和捕捉函数。奇怪的是,通过这么小的量来改变它通常足以超越错误并获得我需要的结果。为了避免这些错误,我打算在我的一些操作中构建一种带有稍微改变值的重试机制。所以我试图弄清楚如何计算这个稍微改变的值。
答案 0 :(得分:1)
使用简单的操作:
SELECT col
, col + POW(0.1,(LENGTH(regexp_replace(CAST(col % 1 AS VARCHAR), '[0]+$', ''))-2))*0.0001 AS result
FROM tab;
的 SqlFiddleDemo
强>
col % 1
- 获取分数部分CAST
到字符串REGEX_REPLACE
- 删除尾随0
LENGTH
- 获取字符串的长度 - 2
(0.
部分)POW(0.1, ...)
- 获取乘数0.0001
更简单:
号码 - >文字 - >删除尾随0 - >追加0001
- >编号
SELECT col,
CAST(regexp_replace(CAST(col * 1.0 AS VARCHAR), '[0]+$', '') || '0001' AS NUMERIC(30,20)) AS result
FROM tab;
的 SqlFiddleDemo
强>
输出:
╔═════════════╦════════════════╗
║ col ║ result ║
╠═════════════╬════════════════╣
║ 2 ║ 2.0001 ║
║ 2.01 ║ 2.010001 ║
║ 2.05000103 ║ 2.050001030001 ║
╚═════════════╩════════════════╝
答案 1 :(得分:1)
我想在没有pow()
的情况下这样做。
函数中的查询仅使用文本操作和强制转换。
它捕获一个整数的特殊情况。
create or replace function add_4_pos_digits (val numeric)
returns numeric language sql as $$
select val+ ('.' || repeat('0', d) || '1')::numeric
from (
select case d when 0 then 3 else d+ 2 end d
from (
select strpos(reverse(rtrim(val::text, '0')), '.') d
) q
) q;
$$;
create table example (val numeric);
insert into example values (1), (1.1), (1.01), (1.00001);
select val, add_4_pos_digits(val)
from example;
val | add_4_pos_digits
---------+------------------
1 | 1.0001
1.1 | 1.10001
1.01 | 1.010001
1.00001 | 1.000010001
(4 rows)