SQL Server ROUND not working - sql

I have a table where one column is Price (decimal(18,9)) and another Volume (bigint).
I am multiplying both values and then applying round function but nothing works.
I want it to be 2 decimal place precision. How to do it?
SELECT
CAST((Price * Volume) AS decimal(38,2)) test1,
ROUND((Price * Volume), 2) 'VolumePrice',
CONVERT(DOUBLE PRECISION, (Price * Volume)) 'test2'
FROM a
Table values are something like this:
Price Volume
-------------------------
63.380000000 131729
63.380000000 61177
44.860000000 246475
44.860000000 246475
44.860000000 63937
97.990000000 84620
191.650000000 438821
I want to simply multiply the price by the volume, to get a total value amount.

ROUND() just changes the decimal value up or down, doesn't change the data type precision.
What you want is to convert to DECIMAL with a scale of 2.
SELECT
CONVERT(DECIMAL(18,2), Price * Volume) AS DecimalConversion
FROM
A
Converting a decimal of higher scale (Price * Volume) to a lower one will automatically round the last digit:
SELECT
CONVERT(DECIMAL(18,2), '1.901999'), -- 1.90
CONVERT(DECIMAL(18,2), '1.909999'), -- 1.91
CONVERT(DECIMAL(18,2), '1.905999'), -- 1.91
CONVERT(DECIMAL(18,2), '1.904999') -- 1.90

When an operator combines two expressions of different data types, the rules for data type precedence specify that the data type with the lower precedence is converted to the data type with the higher precedence
source: MSDN docs
In SQL Server precedence order for data types in question is :
decimal
bigint
So bigint is converted to implicitly converted to decimal.
If you need your desired results you should simply do
SELECT
VolumePrice= cast(Price * Volume as decimal(18,2) )
FROM a
See working demo

Related

I want my data upto 6 decimal places in impala

I have a double type column in impala
while I am trying to cut it upto some decimal places
I got this error
ERROR: AnalysisException: No matching function with signature: truncate(DOUBLE, TINYINT).
e.g select truncate(cast(0.4893617021276596 as double),7);
any workaround will be welcome
You can use round():
select round(col, 6)
If you actually want a truncate, then subtract 0.0000005:
select round(col - 0.0000005, 6)
Using the DECIMAL type, it is possible to represent numbers with greater precision than the FLOAT or DOUBLE types can represent.
The maximum allowed precision and scale of the DECIMAL type are both 38.
Precision is the total number of digits, regardless of the location of the decimal point.
Scale is the number of digits after the decimal place.
To represent the number 8.54 without a loss of precision, you would need a
DECIMAL type with precision of at least 3, and scale of at least 2.
Example:
Note that the DECIMAL(17,16) type means there is a total of 17 digits, with 16 of them after the decimal point.
DECIMAL(17,16) 3.1415926535897932
You could ALTER your table with DECIMAL type as follow:
ALTER TABLE my_table CHANGE field field DECIMAL(precision, scale);
or as suggest #Gordon Linoff, you could use round() function.

What is the correct order? Should it be Round -> Cast or Cast -> Round

What should be the correct order when I am trying to round?
,CAST(ROUND(COUNT(FIRE_SAFETY.DATE_COMPLETED) * 100.0 / COUNT(FIRE_SAFETY.EESS_ID),2) as decimal(16,2)) AS Percentage
,ROUND(CAST(COUNT(FIRE_SAFETY.DATE_COMPLETED) * 100.0 / COUNT(FIRE_SAFETY.EESS_ID) as decimal(16,2)),2) AS Percentage
If you need answer to two decimal places, you should just use cast to decimal(n,2).
COUNT() function returns integer. When an operator combines two expressions of different data types, the rules for data type precedence specify that the data type with the lower precedence is converted to the data type with the higher precedence.
So any operation with 100.0 results to implicit decimal conversion to 100.0 type i.e. with decimal position.
So below statement should be sufficient
,CAST(COUNT(FIRE_SAFETY.DATE_COMPLETED) * 100.0 / COUNT(FIRE_SAFETY.EESS_ID) as decimal(16,2)) AS Percentage
See this MSDN link on how precision and scale gets impacted in SQL server based on combination types in an expression.
Also another mSDN link on the precedence rules.
First we should convert/cast and then round.
From documentation for ROUND :
ROUND ( numeric_expression , length [ ,function ] )
It's the same thing as long as you are rounding up to the same amount of decimals as the scale of the decimal conversion.
Converting to DECIMAL with lower scale automatically rounds the last digit.
SELECT
CONVERT(DECIMAL(18,2), '1.009'), -- 1.01
CONVERT(DECIMAL(18,2), '1.005'), -- 1.01
CONVERT(DECIMAL(18,2), '1.004'), -- 1.00
CONVERT(DECIMAL(18,2), '1.001') -- 1.00
Rounding after converting to decimal (with the same amount of decimals) is pointless while converting to decimal after rounding will just reduce it's scale.
DECLARE #BigDecimal DECIMAL(30,10) = '1.123456789'
SELECT
Original = #BigDecimal, -- 1.1234567890
Rounded = ROUND(#BigDecimal, 2), -- 1.1200000000
RoundedThenDecimal = CONVERT(DECIMAL(18,2), ROUND(#BigDecimal, 2)), -- 1.12
Decimal = CONVERT(DECIMAL(18, 2), #BigDecimal), -- 1.12
DecimalThenRounded = ROUND(CONVERT(DECIMAL(18, 2), #BigDecimal), 2) -- 1.12
Conclusion: just cast to decimal with the scale you need and forget about rounding.

Round a value to two decimal places in SQL

I am trying to round a value in SQL, here is the code that I have:
select round(600.000,2)
How do I get the value 600.00?
Instead of round() convert to a decimal:
select cast(600.000 + 0.5 as decimal(10, 2) )
round() changes the value but it might not change the type of the result. Hence, you might still see extra decimal points (depending on the database and the application). Converting to a decimal with two digits of precision converts both the value and the type.

How to convert decimal to scientific in SQL Server 2008 R2

I have a table named Product. The table looks like this:
ID Product Volume
1 xyz 4654.000000000000000
2 abc 121.000000000000000
I want to represent Volume in a scientific notation. Volume is of datatype decimal(20,8).
How can I do this conversion?
Normally, the formatting and presentation of data should be done by UI, on the client side, but if you insist...
DECLARE #t decimal(20,8) = 4654.000000000000000;
SELECT #t, CONVERT(nvarchar(32), CAST(#t as float), 2)
result
4654.00000000 4.654000000000000e+003
First CAST decimal to float (please note, it may loose precision), then CONVERT float to nvarchar using style 2:
Always 16 digits. Always use in scientific notation.
Note
float type has only 15 digits of precision, so it can't store your decimal(20,8) without loss of precision.
declare #t decimal(20,8)=132423423421.00000000
print cast(#t as float)
you can cast volume field to float in select statement and then you will get scientific notation of it as shown above.

sql server round function not working well

I am using sql server 2000 and facing round function issue like the following statement working fine.
SELECT ROUND(5 * 7.83, 1)
The result will be 39.2
But when I get these values from the table, it gives 39.1, meaning it truncates and does not round up.
SELECT ROUND(rate * qty, 1)
FROM tbl
The result will be 39.1
rate and qty columns data types are float. Insert 5 in qty and 7.83 in rate, then check it. How I can fix it?
Convert the table values to real,
SELECT ROUND(convert(real,rate)*convert(real,qty),1)
Your sample simply query is not reflective of the data types involved.
Try these two instead:
SELECT ROUND(5 * 7.83, 1)
SELECT ROUND(cast(5 as float) * cast(7.83 as float), 1)
The 2nd one matches your table data types. Float datatypes are not meant for precise decimal calculations, use a decimal type for those instead.
What Every Computer Scientist Should Know About Floating-Point Arithmetic
Without losing too much precision for normal numbers, you can just cast to decimal on the fly to force human-comprehensible decimal arithmetics, e.g.
SELECT ROUND(cast(rate as decimal(10,5)) * cast(qty as decimal(10,5), 1)
FROM tbl