我有一个重移表,其中有一个小数列(38, 29),但是原始数据的最大整数部分是6,小数位数是12,即十进制(18,12)。但该表是使用最大精度和小数位数创建的。因此,其中的所有数据在刻度部分的末尾都有
0's
作为填充。
例如:
12345.123456789112300000000000000000000
表中所有数据如上例。
现在我正在使用以下查询从表中检索数据。
select cast(column as decimal(30,6)) from table;
我得到的输出是
12345.123456
但是当我尝试下面的查询时
select cast(12345.123456789112300000000000000000000 as decimal(30,6)) from table;
我得到的输出是
12345.123457
我想知道为什么会发生这种情况。当我在表中转换列时,它没有四舍五入到其最高值,它只是截断。 但是当我尝试使用小数本身时,它会被截断并且四舍五入。
我还想知道如何在表本身中实现第二个查询的结果。
所以这归结为什么时候是演员阵容而不是演员阵容。 如果我将整数转换为 int 它什么也不做。 只要数据适合,将 varchar 转换为较短的 varchar 几乎一样简单。 将小数转换为较低小数位的小数也是一个简单的操作,因为它不会更改数据类型,而只是更改数据的某些属性(小数位)。 您希望 Redshift 在您进行此转换时隐式对值进行舍入,但事实并非如此。 (我会让数据库哲学家辩论这是否是一个错误。)
这里有一个简单的例子来强调这一点:
drop table if exists goo;
create table goo (rownum int, num decimal(30,6));
insert into goo select 1, 12345.123456789112300000000000000000000::text;
insert into goo select 2, 12345.123456789112300000000000000000000::decimal(38,29);
insert into goo select 3, 12345.123456789112300000000000000000000::double;
select rownum, num::text from goo;
在所有 3 个示例中,都隐式转换为表中列“num”的数据类型。 但是您可以看到进入表中的内容是不同的。 很多实验都可以这样进行。 (请注意,我将结果转换为文本以避免任何工作台精度变化。)
您的情况的答案是显式对值进行 ROUND() 。