使用場景:數據庫
在進行多維度彙總數據時,須要將不一樣數據類型,不一樣數據精度的數據合併成一張表時,相關計算出現精度丟失問題。函數
問題排查: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這樣的出力結果 )