Otomatik ondalık yuvarlama sorunu


11

Soru nispeten basit. Orta sonuçları büyük ondalık olan 3 sütun hesaplamak gerekir ve SQL Server ile temelde herhangi bir döküm / dönüştürmek ne olursa olsun ondalık yuvarlama ile ilgili bir sorun haline çalışıyorum.

Örneğin, 1234/1233 olarak basit bir bölünme yapalım. Bir hesap makinesi 1.00081103000811 üretecektir. Ancak bunu SQL Server'da yaptığımda aşağıdakileri elde ederiz:

-- 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

Bu otomatik yuvarlama neden oluşur? Tablo çeşitli farklı değerler içerebileceğinden, bir sayının (int veya dec kısmı) ne kadar büyük olacağından emin olamadığınızda, delice uzun ondalık değerleri hesaplamanın en iyi yolu nedir?

Teşekkürler!

Yanıtlar:


17

tl; Dr.

SQL dilinde hesaplamalar yapma

Uzun

Sonuç ölçeği ve kesinliği burada MSDN'de iyi tanımlanmıştır . Gerçekten sezgisel değil. Bununla birlikte, basit olarak, giriş ölçekleri yüksek olduğunda hassasiyet kaybolur, çünkü sonuç ölçeklerinin eşleşen bir hassasiyet düşüşüyle ​​38'e düşürülmesi gerekir.

Bir şeyleri onaylamak için

  • İlk örnekteki ekstra CAST değeriniz yalnızca sıfır ekleyin
  • Kesme, MSDN bağlantım uyarınca gerçekleşiyor (2. örnek)
  • Sabitleri olan 3. örnekte, yeterli (5,1) ve 18,14) ondalık değerler ima edilmiştir.
    Bu, sonuç ölçeğinin ve hassasiyetinin kesilmediği anlamına gelir (bkz. Darbe)

1. ve 3. vakalar hakkında daha fazla bilgi ..

Bir bölümün sonuç ölçeği max(6, s1 + p2 + 1):

  • İlk örnek, bu 38. Hassas düşürülür 77 (bkz 6 minimuma benzer konuyu aşağı zorlanır olan bu )
  • Üçüncü örnek, bu 24'tür, bu nedenle hassasiyetin ayarlanması gerekmez

Bazı seçenekleriniz var

  • istemci kodunda hesaplayın, örneğin .net
  • .net hesaplamaları yapmak için CLR işlevlerini kullanma
  • doğruluk kaybıyla yaşamak
  • şamandıra kullanın ve en iyi 15 önemli rakamla yaşayın

Sonunda, bunu SO /programming/423925/t-sql-decimal-division-accuracy/424052#424052 adresinde görebilirsiniz.


1

Bunun yardımcı olup olmadığından emin değilim ama benim için geçici tablo sütunum ondalık olarak ayarlandı, insert'ten (ondalık (15,2), 0.65) insert'ten temp_table'a geçiyordum. Bu otomatik yuvarlama, geçen sütunla eşleşmesi için sütun türünü ondalık (16,2) olarak değiştirdim. Tablo şimdi 0,65 depolamaktadır.


1

Etrafta bir iş yapmak zorunda kaldım. İşte yaptım:

-----------------------------------
DECLARE @DENIED INT  = 33443
DECLARE @PAID INT = 148353
DECLARE @PCT Decimal (6,2)

SET @PCT = (@DENIED * 100.00 / @PAID)  -- Instead of dividing by 100, I included decimals

SELECT
@DENIED AS DEN
,@PAID AS PAID
,@PCT AS PCT

Sonuçlar:

DEN PAID    PCT
-----   ----    -----
33443   148353  22.54   -- Instead of 22.00

Bu yardımcı olur umarım.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.