PostgreSQL中5.0/2为何返回scale16的2.5000000000000000而非scale1的2.5?
问题描述
执行以下SQL语句:
select 5.0 / 2 , pg_typeof(5.0 / 2);
得到的查询结果如下:
| pg_typeof | |
|---|---|
| 2.5000000000000000 | numeric |
相关疑问:
- 为何执行结果是
2.5000000000000000? - 明明将
2.5插入numeric类型列或从中查询时,只会得到2.5,不会有多余的末尾零。 - 期望得到精度(scale)为1、无多余末尾零的
2.5,而非精度达16的结果。
原因与解决方法
原因分析
在PostgreSQL中,5.0属于默认精度为16、小数位数为1的numeric类型,整数2会被隐式转换为numeric参与运算。执行除法时,PostgreSQL遵循numeric类型运算规则:除法结果的小数位数取操作数中小数位数的最大值加10,最终导致结果小数位数被扩展到16位,因此显示出多余的末尾零。
而当你将2.5插入numeric类型列时,若列定义了指定小数位数,PostgreSQL会按定义保留位数;若列是未指定精度的numeric,存储时会保留有效位数,查询时也会按有效位数显示,不会补零。
解决方法
若要得到精度为1的2.5,可通过以下方式实现:
- 使用
ROUND()函数指定小数位数:SELECT ROUND(5.0 / 2, 1), pg_typeof(ROUND(5.0 / 2, 1)); - 使用
CAST()转换为指定精度的numeric类型:SELECT CAST(5.0 / 2 AS NUMERIC(5,1)), pg_typeof(CAST(5.0 / 2 AS NUMERIC(5,1))); - 使用
TRIM()函数去除末尾的零:SELECT TRIM(TRAILING '0' FROM (5.0 / 2)::TEXT)::NUMERIC, pg_typeof(TRIM(TRAILING '0' FROM (5.0 / 2)::TEXT)::NUMERIC);
内容的提问来源于stack exchange,提问作者Bek
相关产品推荐
相关产品推荐

