Vấn đề làm tròn số thập phân tự động


11

Câu hỏi tương đối đơn giản. Tôi cần tính toán 3 cột trong đó kết quả giữa là số thập phân rất lớn và tôi đang gặp vấn đề sớm với SQL Server về cơ bản làm tròn số thập phân bất kể mọi chuyển đổi / chuyển đổi.

Ví dụ: hãy thực hiện một phép chia đơn giản là 1234/1233. Một máy tính sẽ tạo ra 1.00081103000811. Nhưng khi tôi làm điều này trên SQL Server, chúng tôi nhận được như sau:

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

Tại sao làm tròn tự động này xảy ra? Và cách tốt nhất để tính các giá trị thập phân cực kỳ dài khi bạn không thể chắc chắn một số lớn (phần int hay phần dec) sẽ như thế nào, vì bảng có thể chứa các giá trị khác nhau?

Cảm ơn!

Câu trả lời:


17

tl; dr

Đừng tính toán bằng ngôn ngữ SQL

Lâu hơn

Thang đo kết quả và độ chính xác được xác định rõ ở đây trên MSDN . Nó không trực quan, thực sự. Tuy nhiên, về mặt đơn giản, độ chính xác bị mất khi thang đo đầu vào cao vì thang đo kết quả cần được giảm xuống 38 với độ chính xác phù hợp.

Để xác nhận mọi thứ

  • CAST thêm của bạn trong ví dụ đầu tiên chỉ cần thêm số không
  • Việc cắt xén xảy ra theo liên kết MSDN của tôi (ví dụ thứ 2)
  • Ví dụ thứ 3 với các hằng số đã ngụ ý các giá trị thập phân vừa đủ (5,1) và 18,14).
    Điều này có nghĩa là thang đo kết quả và độ chính xác không bị cắt ngắn (xem đòn)

Thêm về trường hợp thứ 1 và thứ 3 ..

Thang đo kết quả cho một bộ phận là max(6, s1 + p2 + 1):

  • Ví dụ đầu tiên, đây là 77 được giảm xuống 38. Độ chính xác bị ép xuống tương tự, chịu mức tối thiểu là 6 (xem phần này )
  • Ví dụ thứ ba, đây là 24 nên độ chính xác không cần điều chỉnh

Bạn có một số lựa chọn

  • tính toán trong mã máy khách, vd .net
  • sử dụng các hàm CLR để thực hiện tính toán .net
  • sống với sự mất chính xác
  • sử dụng float và sống với 15 nhân vật quan trọng nhất

Cuối cùng, hãy xem điều này trên SO /programming/423925/t-sql-decimal-division-accuracy/424052#424052


1

Không chắc điều này có giúp ích gì không nhưng đối với tôi, cột bảng tạm thời của tôi được đặt thành thập phân, tôi đã chuyển đổi convert (thập phân (15,2), 0,65) từ chèn vào temp_table. Đây là tự động làm tròn, tôi đã thay đổi loại cột thành số thập phân (16,2) để phù hợp với những gì được thông qua. Bảng hiện đang lưu trữ 0,65.


1

Tôi đã phải làm một công việc xung quanh. Đây là những gì tôi đã là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

Các kết quả:

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

Hi vọng điêu nay co ich.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.