使用场景:数据库
在进行多维度汇总数据时,须要将不一样数据类型,不一样数据精度的数据合并成一张表时,相关计算出现精度丢失问题。函数
问题排查:spa
在进行分段排查后,找到丢失缘由,SUM函数形成精度丢失blog
场景在现:io
1. 建立表select
CREATE TABLE A_TEST
(
ID_CODE NVARCHAR(10),
VAR1 DECIMAL(17,0) -- DECIMAL(17,0) 作为数量使用 小数位为0,※1 问题
)
CREATE TABLE B_TEST
(
ID_CODE NVARCHAR(10),
VAR2 DECIMAL(19,4) -- 带小数位
)数据类型
CREATE TABLE C_TEST
(
ID_CODE NVARCHAR(10),
VAR3 INT -- 整型 例证
)nio
2. 插入数据im
INSERT INTO A_TEST SELECT 'A001',17 ;d3
INSERT INTO B_TEST SELECT 'B001',123.4567 ;
INSERT INTO C_TEST SELECT 'C001',15 ;
3. SQL各出力结果
① 出力 .0000
select var1 from A_TEST -- DECIMAL(17,0)
union all
select var2 from B_TEST -- DECIMAL(19,4)
② SUM 函数使用对 DECIMAL(17,0)的影响 出力 x 1
select sum(var1) from A_TEST
union all
select var2 from B_TEST
③ SUM函数使用对 DECIMAL(19,4)的影响 出力 .0000
select var1 from A_TEST
union all
select sum(var2) from B_TEST
④ INT 数据类型 出力 .0000
-- C_TEST 使用
select var3 from C_TEST
union all
select var2 from B_TEST
⑤ INT 数据类型 SUM函数使用对结果影响
select sum(var3) from C_TEST
union all
select var2 from B_TEST
⑥ sum() count() avg() max() min()
select 'sum',sum(15.12)
union all
select 'sum',14.2222
select 'count',count(15.12)
union all
select 'count',14.2222
select 'avg',avg(18.66)
union all
select 'avg',14.2222
select 'max',max(18.66)
union all
select 'max',14.2222
select 'min',min(18.66)
union all
select 'min',14.2222
结果说明:
经过上述①-⑤例子,能够看出只有在DECIMAL(17,0)数据类型下,使用了SUM函数,出力的结果才会发生预想外的改变 (预想 .0000 出力 实际 x1 出力)
这里感受DECIMAL(17,0)状况下sum 函数会自动将当前小数位截取掉,和其余类型不在作合并计算,不会产生多位,或者按最大位数展现出力结果
而在union all 时,就按多SQL的最小精度出力,因此,当有SUM(DECIMAL(17,0))状况出现时,UNION ALL的结果集就是没有小数位
⑥这个例子是除了sum() 函数之外union all的状况,能够看到AVG()函数是union all 的2条SQL文的精度和其他的都按照最大精度走
※ 这里暂时说明的是 SQL Server 以后会对比ORACLE MySQL 等基本数据库 (这里注明以后补充案例,ORACLE中,SUM(NUMBER(7,0))在作UNION ALL不会取到 x1这样的出力结果 )