PostgreSQL修剪过多的尾随零:类型为数值,但表达式为文本类型

kzmpq1sx  于 2023-06-22  发布在  PostgreSQL
关注(0)|答案(5)|浏览(223)

我试图清除过多的尾随零,我使用了以下查询...

UPDATE _table_ SET _column_=trim(trailing '00' FROM '_column_');

...我收到了以下错误:
错误:列“column”的表达式类型为text。
我已经玩了引号,因为这通常是它桶下来的文本与数字,但没有任何运气。
CREATE TABLE语法:

CREATE TABLE _table_ (
 id bigint NOT NULL,
 x bigint,
 y bigint,
 _column_ numeric
);
w3nuxt5m

w3nuxt5m1#

您可以将参数和结果强制转换为数字:

UPDATE _table_ SET _column_=trim(trailing '00' FROM _column_::text)::numeric;

还要注意的是,您不像以前那样用单引号引用列名。

jc3wubiy

jc3wubiy2#

Postgres版本13现在带有trim_scale()函数:

UPDATE _table_ SET _column_ = trim_scale(_column_);
oxosxuxt

oxosxuxt3#

trim接受字符串参数,因此_column_必须被强制转换为字符串(例如varchar)。然后,trim的结果必须被转换回numeric

UPDATE _table_ SET _column_=trim(trailing '00' FROM _column_::varchar)::numeric;
sg2wtvxw

sg2wtvxw4#

另一种(可以说是更一致的)从NUMERIC字段中清除尾随零的方法是使用以下内容:

UPDATE _table_ SET _column_ = CAST(to_char(_column_, 'FM999999999990.999999') AS NUMERIC);

请注意,您必须修改FM模式以匹配_column_字段的最大预期precisionscale。有关FM模式修饰符和/或to_char(..)函数的更多详细信息,请参阅PostgreSQL文档这里和这里。
编辑:另外,请参阅gnumed-devel邮件列表上的the following帖子,以获得有关此方法的更详细和更全面的解释。

bd1hkmkf

bd1hkmkf5#

小心这里的所有答案。虽然这看起来像一个简单的问题,但它不是。
如果你有pg 13或更高的,你应该使用trim_scale(关于这个已经有答案了)。如果没有,这是我的“Polyfill”:

DO $x$
BEGIN
IF count(*)=0 FROM pg_proc where proname='trim_scale' THEN
CREATE FUNCTION trim_scale(numeric) RETURNS numeric AS $$
SELECT CASE WHEN trim($1::text, '0') = '.' THEN 0 WHEN trim($1::text, '0')::numeric = $1 THEN trim($1::text, '0')::numeric ELSE $1 END $$
LANGUAGE SQL;
END IF;
END;
$x$;

下面是一个用于测试答案的查询:

WITH test as (SELECT unnest(string_to_array('1|2.0|0030.00|4.123456000|300000|0.00','|'))::numeric _column_)
SELECT _column_ original,
trim(trailing '00' FROM _column_::text)::numeric accepted_answer,
CAST(to_char(_column_, 'FM999999999990.999') AS NUMERIC) another_fancy_one,
CASE WHEN trim(_column_::text, '0') = '.' THEN 0 WHEN trim(_column_::text, '0')::numeric = _column_  THEN trim(_column_::text, '0')::numeric ELSE _column_ END my,
trim_scale(_column_) as the_actual_function FROM test;

好吧……看起来,我试图显示早期答案的缺陷,而只是不能拿出其他测试用例。也许你应该写更多,如果你可以。
我喜欢简短的语法,而不是花哨的SQL关键字,所以我总是使用::在CAST上使用逗号分隔的args函数调用,如trim(trailing '00' FROM _column_)。但这只是个人口味,你应该检查你的公司或团队的标准(并争取改变他们XD)

相关问题