Redshift中Decimal类型转换截断与舍入差异问题咨询
问题解析与解决方案
为什么会出现两种不同的结果?
这其实是Redshift对存储的DECIMAL列值和DECIMAL字面量采取了不同的精度处理逻辑导致的:
- 对于表中存储的
DECIMAL(38,29)列值:虽然你的原始数据是DECIMAL(18,12),但存储时已经被补零到29位小数,变成了一个固定精度的精确值。当你直接执行CAST(column AS DECIMAL(30,6))时,Redshift会直接截断第7位及以后的小数部分,不会触发四舍五入——因为它认为你是要从一个精确存储的值中提取前6位小数,而非对数值进行舍入处理。 - 对于DECIMAL字面量:当你写
CAST(12345.123456789112300000000000000000000 AS DECIMAL(30,6))时,Redshift在解析这个字面量时,会先将其视为一个未被固定到特定精度的数值,转换时会遵循标准的四舍五入规则处理到目标精度,所以会把第7位的7进位,得到12345.123457。
如何在查询表时实现舍入结果?
要让表列的转换也触发四舍五入,最可靠的方式是使用ROUND函数明确指定保留的小数位数,而不是直接用CAST:
SELECT ROUND(column_name, 6) FROM your_table;
这个函数会对DECIMAL(38,29)列中的值进行精确的四舍五入,保留6位小数,得到和字面量转换一致的结果。
如果你一定要结合CAST使用,也可以先通过ROUND处理后再转换(不过ROUND本身返回的就是DECIMAL类型,这一步其实不是必须的):
SELECT CAST(ROUND(column_name, 6) AS DECIMAL(30,6)) FROM your_table;
内容的提问来源于stack exchange,提问作者Gopirengaraj C




