I store træk så det sådan her ud, mit eksempel er forsimplet til variabler, så er det lettere at illustrere:
DECLARE @decimal1 DECIMAL(38,12) = 1.0,
@decimal2 DECIMAL(38,12) = 7.45999999
SELECT @decimal1 / @decimal2
Her ville jeg nok normalt forvente 12 decimaler – når vi definerer en decimal type så angiver vi DECIMAL(precision,scale) altså precision 38 = antallet af tal i alt og scale = 12 antallet af decimaler. Resultatet er:
Hvad sker der lige her?
det vil jeg prøve at forklare. Når SQL Serveren benytte en matematisk operation på 2 datatyper, om det er gange (*) +, – eller dividere (/) 2 decimaler benyttes der en formel for at finde hvilken størrelse resultat decimalen er. Ved division benyttes denne formel:
precision: p1 – s1 + s2 + max(6, s1 + p2 + 1)
scale: max(6, s1 + p2 + 1)
Lad os prøve med et lidt mere simpelt eksempel:
DECLARE @decimal1 DECIMAL(5,3) = 12.345,
@decimal2 DECIMAL(5,3) = 54.321
Jeg benytter formlen oven for:
(p = presicion, s = scale)
P1 = 5, S1 = 3
P2 =5, S2 = 3
Det giver følgende formel:
SELECT 5-3+3 + MAX(6, 3+5+1) AS precision,
MAX(6, 3+5+1) AS scale
Resultatet giver:
precision: 14
scale: 9
Hvilket må betyde at resultat decimalen er en DECIMAL(14,9) lad mig efterprøve den teori:
DECLARE @decimal1 DECIMAL(5,3) = 12.345,
@decimal2 DECIMAL(5,3) = 54.321
SELECT @decimal1 / @decimal2
GO
Hvilket giver følgende resultat… tæl gerne decimalerne.
9 decimaler, så her er regnestykket ikke helt ved siden af 😊
Lad mig efterprøve med DECIMAL(38,12)/ DECIMAL(38,12)
Formlen er stadig den samme:
precision: p1 – s1 + s2 + max(6, s1 + p2 + 1)
scale: max(6, s1 + p2 + 1)
P1 = 38, S1 = 12
P2 = 38, S2 = 12
SELECT 38-12+12+(12+38+1) AS precision,
(12+38+1) AS scale
Det giver Precision 89, Scale 51
Precision kan ikke være højre end 38 og da precision og scale hænger sammen, skal der regnes lidt videre.
Precision: 89 – 38 (38 fordi det er max precision) = 51,
Scale: 51 – (89-38) = 0 … husk formlen scale: max(6, s1 + p2 + 1) så nu har vi max(6,0) hvilket er 6.
Det giver os altså en decimal (38,6) hvilket også er resultatet af:
DECLARE @decimal1 DECIMAL(38,12) = 1.0,
@decimal2 DECIMAL(38,12) = 7.45999999
SELECT @decimal1 / @decimal2
Hvis du skal bruge flere decimaler end 6 for at få det rigtige resultat, må du ændre lidt på datatyperne, for eksempel som dette:
DECLARE @decimal1 DECIMAL(12,11) = 1.0,
@decimal2 DECIMAL(12,11) = 7.45999999
SELECT @decimal1 / @decimal2
Decimaltal og præcision
Tænk over hvor mange decimaler og hvor stor præcisions du har behov for når du definerer decimaltal, det kan give unødig afrunding og trunkering af decimaler.
Du kan læse mere på docs her: https://docs.microsoft.com/en-us/previous-versions/sql/sql-server-2005/ms190476(v=sql.90)?redirectedfrom=MSDN
Tak fordi du læste med. Som altid så er du velkommen til at kontakte mig eller en af mine dygtige kollegaer i Unit IT på tlf.: 88 333 333, hvis du har spørgsmål eller udfordringer med dit SQL miljø.