我有一个带小数的价格列表。
示例:0.513 0.35135 1.6583
我正在尝试选择十进制数字的长度。这就是我的意思:0.513 | 长度=3 0.35135 | 长度=5 1.6583 | 长度=4
我尝试将数字转换为文本,但似乎没有提供正确的结果:
select price, length(cast(price as text)) from table.prices
我也试过这种转换方法:“length(price::text)”
关于如何实现这一目标的任何建议?
我有一个带小数的价格列表。
示例:0.513 0.35135 1.6583
我正在尝试选择十进制数字的长度。这就是我的意思:0.513 | 长度=3 0.35135 | 长度=5 1.6583 | 长度=4
我尝试将数字转换为文本,但似乎没有提供正确的结果:
select price, length(cast(price as text)) from table.prices
我也试过这种转换方法:“length(price::text)”
关于如何实现这一目标的任何建议?
您可以使用scale函数,因为 postgresql 9.6 ;)
select scale(1.12345) as decimal_places;
decimal_places
----------------
5
(1 row)
这个怎么样:
CREATE FUNCTION decimal_places(n numeric) RETURNS int
LANGUAGE SQL IMMUTABLE
AS $$
select coalesce(length(substring(cast($1 as text) from '\..*$')) - 1, 0);
$$;
=> select decimal_places(0.513);
┌────────────────┐
│ decimal_places │
├────────────────┤
│ 3 │
└────────────────┘
此代码有效(请参阅SQLFiddle 演示):
WITH test(x) AS (VALUES (0.513), (0.35135), (1.6583))
SELECT length((x - floor(x))::text)-2
FROM test
只有一个陷阱 - 对于它返回的整数-1
。
为此编写一个 sql 或 plpgsql 函数。(或者更好的是,在您的应用程序中执行此操作:它可能一开始就不属于 Postgres。)
您需要的伪代码是:
如果您正在处理具有指数的东西,请确保首先将值转换为数字,以便将例如扩展1e-12
为0.000000000001
.
在 select 中可以这样使用:
SELECT length((SELECT regexp_matches(price::text,'(\\.\\d+)')::text)), price FROM table.prices