PostgreSQL Trim 尾随零过多:类型为数字,但表达式为文本类型
PostgreSQL Trim excessive trailing zeroes: type numeric but expression is of type text
我正在尝试清除过多的尾随零,我使用了以下查询...
UPDATE _table_ SET _column_=trim(trailing '00' FROM '_column_');
...我收到以下错误:
ERROR: column "_column_" is of
expression is of type text.
我一直在研究引号,因为这通常是文本与数字的区别所在,尽管没有任何运气。
CREATE TABLE
语法:
CREATE TABLE _table_ (
id bigint NOT NULL,
x bigint,
y bigint,
_column_ numeric
);
您可以将参数和结果转换回数字:
UPDATE _table_ SET _column_=trim(trailing '00' FROM _column_::text)::numeric;
另请注意,您没有像以前那样用单引号引用列名。
trim
采用字符串参数,因此 _column_
必须转换为字符串(例如 varchar
)。然后, trim
的结果必须转换回 numeric
.
UPDATE _table_ SET _column_=trim(trailing '00' FROM _column_::varchar)::numeric;
另一种(可以说更一致)从 NUMERIC
字段中清除尾随零的方法是使用如下内容:
UPDATE _table_ SET _column_ = CAST(to_char(_column_, 'FM999999999990.999999') AS NUMERIC);
请注意,您必须修改 FM
模式以匹配 _column_
字段的最大预期 precision
和 scale
。有关 FM
模式修饰符 and/or to_char(..)
函数的更多详细信息,请参阅 PostgreSQL 文档 here and here.
编辑:此外,请参阅 gnumed-devel
邮件列表中的 the following post,以获取有关此方法的更详尽的解释。
Postgres 版本 13 现在带有 trim_scale()
函数:
UPDATE _table_ SET _column_ = trim_scale(_column_);
请仔细阅读此处的所有答案。虽然这看起来是个简单的问题,但其实不然。
如果您的第 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(::text, '0')::numeric = THEN trim(::text, '0')::numeric ELSE END $$
LANGUAGE SQL;
END IF;
END;
$x$;
这里是测试答案的查询:
WITH test as (SELECT unnest(string_to_array('1|2.0|0030.00|4.123456000|300000','|'))::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')::numeric = _column_ THEN trim(_column_::text, '0')::numeric ELSE _column_ END my FROM test;
嗯...看起来,我正试图展示早期答案的缺陷,但无法提出其他测试用例。也许你应该写更多,如果可以的话。
我喜欢简短的语法而不是花哨的 sql 关键字,所以我总是在 CAST
上使用 :: 并在 trim(trailing '00' FROM _column_)
等构造上使用逗号分隔的 args 进行函数调用。但这只是个人品味,你应该检查你的公司或团队的标准(并争取改变他们 XD)
我正在尝试清除过多的尾随零,我使用了以下查询...
UPDATE _table_ SET _column_=trim(trailing '00' FROM '_column_');
...我收到以下错误:
ERROR: column "_column_" is of expression is of type text.
我一直在研究引号,因为这通常是文本与数字的区别所在,尽管没有任何运气。
CREATE TABLE
语法:
CREATE TABLE _table_ (
id bigint NOT NULL,
x bigint,
y bigint,
_column_ numeric
);
您可以将参数和结果转换回数字:
UPDATE _table_ SET _column_=trim(trailing '00' FROM _column_::text)::numeric;
另请注意,您没有像以前那样用单引号引用列名。
trim
采用字符串参数,因此 _column_
必须转换为字符串(例如 varchar
)。然后, trim
的结果必须转换回 numeric
.
UPDATE _table_ SET _column_=trim(trailing '00' FROM _column_::varchar)::numeric;
另一种(可以说更一致)从 NUMERIC
字段中清除尾随零的方法是使用如下内容:
UPDATE _table_ SET _column_ = CAST(to_char(_column_, 'FM999999999990.999999') AS NUMERIC);
请注意,您必须修改 FM
模式以匹配 _column_
字段的最大预期 precision
和 scale
。有关 FM
模式修饰符 and/or to_char(..)
函数的更多详细信息,请参阅 PostgreSQL 文档 here and here.
编辑:此外,请参阅 gnumed-devel
邮件列表中的 the following post,以获取有关此方法的更详尽的解释。
Postgres 版本 13 现在带有 trim_scale()
函数:
UPDATE _table_ SET _column_ = trim_scale(_column_);
请仔细阅读此处的所有答案。虽然这看起来是个简单的问题,但其实不然。
如果您的第 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(::text, '0')::numeric = THEN trim(::text, '0')::numeric ELSE END $$
LANGUAGE SQL;
END IF;
END;
$x$;
这里是测试答案的查询:
WITH test as (SELECT unnest(string_to_array('1|2.0|0030.00|4.123456000|300000','|'))::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')::numeric = _column_ THEN trim(_column_::text, '0')::numeric ELSE _column_ END my FROM test;
嗯...看起来,我正试图展示早期答案的缺陷,但无法提出其他测试用例。也许你应该写更多,如果可以的话。
我喜欢简短的语法而不是花哨的 sql 关键字,所以我总是在 CAST
上使用 :: 并在 trim(trailing '00' FROM _column_)
等构造上使用逗号分隔的 args 进行函数调用。但这只是个人品味,你应该检查你的公司或团队的标准(并争取改变他们 XD)