A questão é relativamente simples. Eu preciso calcular 3 colunas onde os resultados médios são decimais enormes e estou tendo um problema no início com o SQL Server basicamente arredondando os decimais, independentemente de qualquer conversão/conversão.
Por exemplo, vamos fazer uma divisão simples como 1234/1233. Uma calculadora produzirá 1.00081103000811. Mas quando faço isso no SQL Server, obtemos o seguinte:
-- Result: rounded at 1.000811000... with trailing zeroes up until the 37 precision
SELECT CAST(CAST(1234 AS DEC(38,34))/CAST(1233 AS DEC(38,34)) AS DEC(38,37))
-- Result: rounded at 1.000811
SELECT CONVERT(DECIMAL(38,32), 1234)/CONVERT(DECIMAL(38,32),1233)
-- Correct result at 1,00081103000811
-- But this requires the zeroes to be put in manually when you don't
-- even know the precision of the end result
SELECT 1234.0/1233.00000000000000
Por que esse arredondamento automático ocorre? E qual é a melhor maneira de calcular valores decimais insanamente longos quando você não pode ter certeza de quão grande será um número (a parte int ou dec), já que a tabela pode conter vários valores diferentes?
Obrigado!
tl; dr
Não faça cálculos em linguagem SQL
Mais tempo
A escala e a precisão do resultado estão bem definidas aqui no MSDN . Não é intuitivo, na verdade. No entanto, em termos simples, a precisão é perdida quando as escalas de entrada são altas porque as escalas de resultado precisam ser reduzidas para 38 com uma queda de precisão correspondente.
Para confirmar as coisas
Isso significa que a escala e a precisão do resultado não têm truncamento (veja o golpe)
Mais sobre o 1º e 3º casos..
A escala de resultado para uma divisão é
max(6, s1 + p2 + 1)
:Você tem algumas opções
Finalmente, veja isso em SO https://stackoverflow.com/questions/423925/t-sql-decimal-division-accuracy/424052#424052
Não tenho certeza se isso ajuda, mas para mim minha coluna da tabela temporária foi definida como decimal, eu estava passando convert(decimal(15,2), 0.65) da inserção para temp_table. Este foi o arredondamento automático, mudei o tipo de coluna para decimal(16,2) para corresponder ao que estava sendo passado. A tabela agora está armazenando 0,65.
Tive que dar um jeito. Aqui está o que eu fiz:
Resultados:
Espero que isto ajude.