Diviso de decimal com inteiro, como ficam as casas decimais?

Surgiu a seguinte dvida no trabalho esse dias que foi mais ou menos assim:

Tenho duas colunas e estou realizando uma diviso entre elas. Qual vai ser o tipo retornado? O SQL Server segue a ordem de precedncia do tipo do dado?

De bate pronto, a resposta um “Sim, ele sempre vai seguir a ordem de precedncia e vai retornar o tipo de dado que voc est usando que possui maior precedncia.”
Porm (sempre tem um porm), isso no valido para os tipos decimais.
Para entender isso, precisamos entender trs conceitos nos tipo de dados: Tamanho (length), preciso (precision) e escala (scale).
Quando voc executar um ‘sp_help TB_Decimal’ (a.k.a. “ALT+F1 na tabela”), voc vai ver trs colunas:
– Length: quando falamos de tipos numricos, ele retrata o tamanho em bytes que a coluna vai ocupar. Quando um tipo texto ((n)char, (n)varchar) a quantidade de caracteres.
– Prec: Quantidade de digitos em um nmero (111 = preciso de 3, 111.22 = preciso de 5).
– Scale: Quantidade de dgitos nas casas decimais (111 = escala com 0 dgitos, 111.22 = escala com 2 dgitos)
Obs: A preciso que voc usar, vai mudar o tamanho que voc ver no length.

Veja o exemplo abaixo:

 

Note que at para a diviso entre dois nmeros decimais, ele no seguiu as casas decimais especificadas na tabela.
Vamos ver como o clculo feito (e aqui, seremos bem tericos), usando a diviso do tipo decimal por um inteiro (valor1 / valor2), alinhando que cada coluna uma expresso (chamada aqui de ‘e’), que possui uma preciso (‘p’) e uma escala (‘s’).
Dessa forma, temos que:
Valor1 = e1, com preciso p1 e escala s1
Valor2 = e2, com preciso p2 e escala s2

As frmulas para o calculo da preciso e da escala para a diviso so:

Preciso
p1 – s1 + s2 + max(6, s1 + p2 + 1)
15 – 2 + 0 + max(6, 2 + 10 +1)
13 + max(6, 13)
13 + 13
26

 

Escala:
max(6, s1 + p2 + 1)
max(6, 2 + 10 + 1)
max(6, 13)
13

O resultado da consulta foi 5.0000000000000, fechando com os 13 dgitos que tivemos na escala. Poderamos ainda ter um nmero onde a diviso teria como resultado mais de 13 dgitos significativos para que ele no desse overflow.

Vamos ver agora a questo do decimal / decimal

Preciso:
p1 – s1 + s2 + max(6, s1 + p2 + 1)
15 – 2 + 2 + max(6, 2 + 15 +1)
15 + max(6, 118)
15 + 18
33

Escala
max(6, s1 + p2 + 1)
max(6, 2 + 15 + 1)
max(6, 18)
18

Resultado da consulta: 5.000000000000000000.

TL/DR: Quando for realizar uma operao onde o resultado ser um tipo decimal, prepare-se para tratar as casas decimais. 🙂

Fontes:

Para saber mais sobre as frmulas de clculo para as demais operaes, veja em:
https://docs.microsoft.com/en-us/sql/t-sql/data-types/precision-scale-and-length-transact-sql
Para saber a ordem de precedncia de dados
https://docs.microsoft.com/en-us/sql/t-sql/data-types/data-type-precedence-transact-sql

 

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.