3

我有一个带小数的价格列表。

示例: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)”

关于如何实现这一目标的任何建议?

4

5 回答 5

5

您可以使用scale函数,因为 postgresql 9.6 ;)

select scale(1.12345) as decimal_places;
 decimal_places 
----------------
              5
(1 row)

于 2019-09-20T02:36:45.767 回答
3

这个怎么样:

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 │
└────────────────┘
于 2013-11-11T16:39:06.657 回答
1

此代码有效(请参阅SQLFiddle 演示):

WITH test(x) AS (VALUES (0.513), (0.35135), (1.6583))
SELECT length((x - floor(x))::text)-2
FROM test

只有一个陷阱 - 对于它返回的整数-1

于 2013-11-11T10:27:35.847 回答
0

为此编写一个 sql 或 plpgsql 函数。(或者更好的是,在您的应用程序中执行此操作:它可能一开始就不属于 Postgres。)

您需要的伪代码是:

  1. 将数字转换为文本。
  2. 找到点的位置。如果没有,则返回零,否则相应地计算长度。

如果您正在处理具有指数的东西,请确保首先将值转换为数字,以便将例如扩展1e-120.000000000001.

于 2013-11-11T11:38:22.147 回答
0

在 select 中可以这样使用:

SELECT length((SELECT regexp_matches(price::text,'(\\.\\d+)')::text)), price FROM table.prices
于 2019-08-12T18:19:35.147 回答