Thắc mắc về kiểu dữ liệu money và decimal trong SQL Server

Em đang học SQL server và có thắc mắc đến đầu ra của dữ liệu dựa trên 2 kiểu dữ liệu chính là: moneydecimal.

DECLARE
    @mon1 MONEY,
    @mon2 MONEY,
    @mon3 MONEY,
    @mon4 MONEY,
    @num1 DECIMAL(19,4),
    @num2 DECIMAL(19,4),
    @num3 DECIMAL(19,4),
    @num4 DECIMAL(19,4)

    SELECT
    @mon1 = 100, @mon2 = 339, @mon3 = 10000,
    @num1 = 100, @num2 = 339, @num3 = 10000

    SET @mon4 = @mon1/@mon2*@mon3
    SET @num4 = @num1/@num2*@num3

    SELECT @mon4 AS moneyresult,
    @num4 AS numericresult

Output: 2949.0000 2949.8525
Tại sao cùng 1 phép tính toán mà money là kiểu dữ liệu số thực nhưng nó lại bị mất thông tin phần thập phân, trong khi đó kiểu decimal lại có thể tính toán chính xác ạ. Xin cảm ơn các cao nhân rất nhiều !!!

Thực ra money vẫn là số nguyên 64 bit thôi.

Cái này thuộc dạng hỏi đố, nhưng thật ra không có gì là khó hiểu ở đây cả. Mấu chốt của vấn đề là kiểu MONEY chỉ có 4 số lẻ*, trong khi DECIMAL có 19.

Vì vậy:

  • Sau phép chia đầu tiên nó chỉ giử được giá trị là 0.2949

  • Lấy 0.2949 * 10,000 = 2949.0000
    Tương tự, nếu nhân với 100k, kết quả sẽ là 29490, thay vì 29498 !

      @mon1/@mon2           @mon1/@mon2*@mon3     @mon1/@mon2*100000
      --------------------- --------------------- ------------------
      0.2949                2949.00               29490.00          
    

Trong khi đó kiểu DECIMAL vẫn giử được 19 số lẻ sau phép chia đầu tiên, vì vậy nó sẽ lấy:

0.2949852507374631268 * 10,000 = 2949.8525073746313

Do đã khai báo DECIMAL lấy 4 số lẽ, nên phần dư bị cắt đi, chỉ giử lại: 2949.8525

@num1/@num2              @num1/@num2*@num3   @num1/@num2*100000
------------------------ ------------------- ------------------
0.2949852507374631268    2949.852507         29498.525073746313
2 Likes

Thường mình sẽ dùng float hoạc decimal để lưu trữ chứ không sử dụng kiểu money.

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?