SQL Server Ondalık İşlem Doğru Değil
Bu basit işlemi SQL sunucusunda çalıştırdığımda:
Select 800.0 /30.0
26.666666 değerini alıyorum, burada 6 basamak için yuvarlasa bile 26.666667 olmalıdır. Hesaplamanın doğru olmasını nasıl sağlayabilirim? Çevrimiçi olarak araştırmaya çalıştım ve işlemden önce her işleneni yüksek hassasiyetli bir ondalık sayıya çevirdiğim bir çözüm buldum, ancak bu benim için uygun olmayacak çünkü çok uzun karmaşık hesaplamalarım var. daha iyi bir çözüm olması gerektiğini düşünüyorum.
Yanıtlar
Kullanan bir bölme olduğunda, SQL Server'da, elde edilen ölçekten sonraki tüm rakamlar yuvarlatılmaz, kesilir. İfadeniz için a decimal(4,1)ve a var decimal(3,1), bu da a decimal(10,6):
Precision = p1 - s1 + s2 + max(6, s1 + p2 + 1)
Scale = max(6, s1 + p2 + 1)
Sonuç olarak, 26.66666666666666~şeklinde kısaltıldı 26.666666.
Hassasiyet ve ölçeğin boyutunu artırarak ve ardından CONVERTgerekli hassasiyet ve ölçeğinize geri dönerek bunu aşabilirsiniz. Örneğin, duyarlık ve ölçeği artırmak decimal(3,1)için decimal(5,2)ve geri dönüştürmek decimal(10,6):
SELECT CONVERT(decimal(10,6),800.0 / CONVERT(decimal(5,3),30.0));
Bu geri döner 26.666667.
Bu yardımcı olabilir:
ROUND (Transact-SQL) kullanın
SELECT ROUND(800.0 /30.0, 5) AS RoundValue;
Sonuç:
RoundValue
26.666670
Sanırım bunun nedeni SQL Server'ın sayılarınızı decimaldeğerler olarak almasıdır (örneğin, 6.6666 ve 6.6667 tam olarak bu değerler, 6 ve üçte ikisi değil) değil float(yaklaşık sayılarla çalışabilir).
floatBaşlangıçta bunu açık bir şekilde a çevirirseniz / dönüştürürseniz , hesaplamalarınızın sorunsuz çalışmasını sağlamalısınız.
İşte arasındaki farkı göstermek için bazı örnekler var int, decimalve floathesaplamalar
- 20'yi 3'e bölme
- 20'yi 3'e bölerek, sonra tekrar 3 ile çarparak (matematiksel olarak 20 olmalıdır).
SELECT (20/3) AS int_calc,
(20/3) * 3 AS int_calc_x3,
(CAST(20 AS decimal(10,3)) /3) AS dec_calc,
(CAST(20 AS decimal(10,3)) /3) * 3 AS dec_calc_x3,
(CAST(20 AS float) /3) AS float_calc,
(CAST(20 AS float) /3) * 3 AS float_calc_x3
aşağıdaki sonuçlarla
int_calc int_calc_x3 dec_calc dec_calc_x3 float_calc float_calc_x3
6 18 6.666666 19.999998 6.66666666666667 20
Senin durumunda kullanabilirsin
Select CAST(800.0 AS float) /30.0
26.6666666666667 ile sonuçlanır
Daha sonra 30 ile çarparsanız, doğru sonucu alır, örneğin,
Select (CAST(800.0 AS float) /30.0) * 30
800 ile sonuçlanır. Ondalık sayılarla ilgilenen çözümler buna sahip olmayacaktır.
Ayrıca, onu bir kayan nokta olarak elde ettiğinizde, bir ondalık sayıya veya bir şekilde int'e dönüştürülene kadar (örneğin, bir tabloya int olarak kaydedilene kadar) bir kayan nokta olarak kalması gerektiğini unutmayın. Yani...
SELECT A.Num / 30
FROM (Select ((CAST(800.0 AS float) /30.0) * 30) AS Num) AS A
yine de 26.6666666666667 ile sonuçlanacaktır
Umarım bu uzun karmaşık hesaplamalarınızda size yardımcı olacaktır.