Operasi Desimal SQL Server Tidak Akurat
Ketika saya menjalankan operasi sederhana ini di SQL server:
Select 800.0 /30.0
Saya mendapatkan nilai 26.666666, di mana meskipun membulatkan 6 digit seharusnya 26.666667. Bagaimana saya bisa mendapatkan perhitungan agar akurat? Saya mencoba mencarinya secara online dan saya menemukan solusi di mana saya mentransmisikan setiap operan ke desimal presisi tinggi sebelum operasi, tetapi ini tidak akan nyaman bagi saya karena saya memiliki banyak perhitungan rumit yang panjang. pikir pasti ada solusi yang lebih baik.
Jawaban
Saat menggunakan pembagian, di SQL Server, angka apa pun setelah skala yang dihasilkan dipotong, tidak dibulatkan. Untuk ekspresi Anda, Anda memiliki a decimal(4,1)dan a decimal(3,1), yang menghasilkan decimal(10,6):
Precision = p1 - s1 + s2 + max(6, s1 + p2 + 1)
Scale = max(6, s1 + p2 + 1)
Akibatnya, 26.66666666666666~terpotong menjadi 26.666666.
Anda dapat menyiasatinya dengan dapat meningkatkan ukuran presisi dan skala, lalu CONVERTkembali ke presisi dan skala yang Anda inginkan. Misalnya, tingkatkan presisi dan skala decimal(3,1)menjadi decimal(5,2)dan ubah kembali menjadi decimal(10,6):
SELECT CONVERT(decimal(10,6),800.0 / CONVERT(decimal(5,3),30.0));
Ini kembali 26.666667.
Ini mungkin membantu:
Gunakan ROUND (Transact-SQL)
SELECT ROUND(800.0 /30.0, 5) AS RoundValue;
Hasil:
RoundValue
26.666670
Saya percaya itu karena SQL Server mengambil angka Anda sebagai decimalnilai (yang tepat misalnya, 6.6666 dan 6.6667 berarti persis nilai-nilai itu, bukan 6 dan dua pertiga) daripada floatnilai (yang dapat bekerja dengan angka perkiraan).
Jika Anda secara eksplisit mentransmisikan / mengubahnya menjadi a floatdi awal, perhitungan Anda akan berjalan lancar.
Berikut beberapa contoh untuk menunjukkan perbedaan antara int, decimaldan floatperhitungan
- Membagi 20 dengan 3
- Membagi 20 dengan 3, kemudian mengalikan dengan 3 lagi (yang secara matematis seharusnya 20).
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
dengan hasil sebagai berikut
int_calc int_calc_x3 dec_calc dec_calc_x3 float_calc float_calc_x3
6 18 6.666666 19.999998 6.66666666666667 20
Dalam kasus Anda, Anda dapat menggunakan
Select CAST(800.0 AS float) /30.0
yang menghasilkan 26.6666666666667
Perhatikan jika Anda kemudian mengalikan kembali dengan 30, hasilnya akan benar, misalnya,
Select (CAST(800.0 AS float) /30.0) * 30
menghasilkan 800. Solusi yang berhubungan dengan desimal tidak akan memiliki ini.
Perhatikan juga bahwa setelah Anda memilikinya sebagai float, maka itu harus tetap menjadi float sampai diubah kembali menjadi desimal atau int (misalnya, disimpan dalam tabel sebagai int). Begitu...
SELECT A.Num / 30
FROM (Select ((CAST(800.0 AS float) /30.0) * 30) AS Num) AS A
akan tetap menghasilkan 26.6666666666667
Mudah-mudahan ini akan membantu Anda dalam perhitungan rumit yang panjang.