Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should you choose the MONEY or DECIMAL(x,y) datatypes in SQL Server?

I'm curious as to whether or not there is a real difference between the money datatype and something like decimal(19,4) (which is what money uses internally, I believe).

I'm aware that money is specific to SQL Server. I want to know if there is a compelling reason to choose one over the other; most SQL Server samples (e.g. the AdventureWorks database) use money and not decimal for things like price information.

Should I just continue to use the money datatype, or is there a benefit to using decimal instead? Money is fewer characters to type, but that's not a valid reason :)

like image 585
Wayne Molina Avatar asked Feb 24 '09 17:02

Wayne Molina


People also ask

What data type should I use for money SQL?

Unlike the DECIMAL data type, the MONEY data type is always treated as a fixed-point decimal number. The database server defines the data type MONEY(p) as DECIMAL(p,2). If the precision and scale are not specified, the database server defines a MONEY column as DECIMAL(16,2).

Which data type is best for currency amounts in SQL Server?

If you need the highest precision, a DECIMAL can use up to 17 bytes for each value. Generally though, I like using DECIMAL(19,4) for currency, which needs 9 bytes and can store numbers 19 digits wide, where the last four digits are after the decimal place.

Should I use float or decimal in SQL?

Float stores an approximate value and decimal stores an exact value. In summary, exact values like money should use decimal, and approximate values like scientific measurements should use float. When multiplying a non integer and dividing by that same number, decimals lose precision while floats do not.

Which is the most appropriate data type for currency?

The best datatype to use for currency in C# is decimal. The decimal type is a 128-bit data type suitable for financial and monetary calculations. The decimal type can represent values ranging from 1.0 * 10^-28 to approximately 7.9 * 10^28 with 28-29 significant digits.


2 Answers

Never ever should you use money. It is not precise, and it is pure garbage; always use decimal/numeric.

Run this to see what I mean:

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

To some of the people who said that you don't divide money by money:

Here is one of my queries to calculate correlations, and changing that to money gives wrong results.

select t1.index_id,t2.index_id,(avg(t1.monret*t2.monret)     -(avg(t1.monret) * avg(t2.monret)))             /((sqrt(avg(square(t1.monret)) - square(avg(t1.monret))))             *(sqrt(avg(square(t2.monret)) - square(avg(t2.monret))))), current_timestamp,@MaxDate             from Table1 t1  join Table1 t2  on t1.Date = traDate             group by t1.index_id,t2.index_id 
like image 136
SQLMenace Avatar answered Oct 03 '22 19:10

SQLMenace


SQLMenace said money is inexact. But you don't multiply/divide money by money! How much is 3 dollars times 50 cents? 150 dollarcents? You multiply/divide money by scalars, which should be decimal.

DECLARE @mon1 MONEY, @mon4 MONEY, @num1 DECIMAL(19,4), @num2 DECIMAL(19,4), @num3 DECIMAL(19,4), @num4 DECIMAL(19,4)  SELECT @mon1 = 100, @num1 = 100, @num2 = 339, @num3 = 10000  SET @mon4 = @mon1/@num2*@num3 SET @num4 = @num1/@num2*@num3  SELECT @mon4 AS moneyresult, @num4 AS numericresult 

Results in the correct result:

moneyresult           numericresult --------------------- --------------------------------------- 2949.8525             2949.8525

money is good as long as you don't need more than 4 decimal digits, and you make sure your scalars - which do not represent money - are decimals.

like image 45
configurator Avatar answered Oct 03 '22 20:10

configurator