How to select only two decimal number without rounding in sql? - sql

My problem is I want to select two decimal number in amount column without rounding up. I have tried use FORMAT but rounding up my values
sql:
SELECT claim_type,amount
FROM detail
table detail :
id claim_type amount
------ -------------------- -------
1 FOOD REFRESHMENT 1.27000
2 FOOD REFRESHMENT 2.35000
I want the output be like this when I select
claim_type amount
-------------------- -------
FOOD REFRESHMENT 1.27
FOOD REFRESHMENT 2.35

This is dependent on the dialect of SQL, but in general your examples won't be rounded by either FORMAT or TRUNCATE analogues. If you have a number such as 2.237 and try to format it to two numbers after the decimal point, it will be rounded up to 2.24 by those functions - but you can always cast it to a string datatype and then simply take a substring. In PostgreSQL:
% select substring(2.237::text, 1, 4);
substring
-----------
2.23
(1 row)

you can also use the Cast function to get decimals values without rounding as below
SELECT Cast(Round(123.419,2,1) as decimal(18,2))

Related

add two zero with decimal if number is complete integer in Oracle SQL column

Column amount contains data like - 200.203, 200, 5.10, 45.20, 10 and 5000213.012
Now I want to select if the number does not include any decimal digit then we add .00 in the returning result.
Expected result - 200.203, 200.00 ,5.10, 45.20 , 10.00 and 5000213.012
You can use TO_CHAR to format the value so that it has at least 2 decimal places:
SELECT value,
TO_CHAR( value, 'FM9999999990.009' ) AS formatted_value
FROM table_name
Which, for the sample data:
CREATE TABLE table_name ( value ) AS
SELECT 200.203 FROM DUAL UNION ALL
SELECT 200 FROM DUAL UNION ALL
SELECT 5.10 FROM DUAL UNION ALL
SELECT 45.20 FROM DUAL UNION ALL
SELECT 10 FROM DUAL UNION ALL
SELECT 5000213.012 FROM DUAL;
Outputs:
VALUE | FORMATTED_VALUE
----------: | :--------------
200.203 | 200.203
200 | 200.00
5.1 | 5.10
45.2 | 45.20
10 | 10.00
5000213.012 | 5000213.012
db<>fiddle here
Following some comments, the OP's question is effectively:
How can I change this number to have a given format?
When you consider that a NUMBER data type has no format and 5, 5.0 and 5.00000 are exactly the same value and the database does not store how many trailing zeroes a decimal value has then this question does not entirely make sense as there is no way to give a number a format.
Instead the question can be formulated as either:
How can I get <insert name of client program> to display numbers so that they always have at least 2 decimal places?
We can't answer this question without knowing the client program so I'll skip it.
Or:
How can I display a number from an Oracle query so that it is formatted with at least 2 decimal places?
Since NUMBERs never have any formatting of their own then this must involve a conversion to another data-type which can represent the number with a format (i.e. a string). So the result is that if you want a NUMBER data type then Oracle will not give it a format (but the client program might) but if you want to change the NUMBER to a string data type then you can give it a format (but it won't be a NUMBER as its now a string that just happens to contain digits) and, as described above, TO_CHAR does that.
This will do:
select to_number(to_char(value, '9999999.99')) from dual;

divide 2 columns in DB2

How to divide 2 columns in DB2. For example I have the below query
select x.planned,y.unplanned,(x.planned /y.unplanned) average from
((select count(1) planned from
(select 1 from table
--------
union all
select 1 from table
--------)) x
join
(select count(1) unplanned from
(select 1 from table
--------
union all
select 1 from table
--------)) y
on 1=1)
This query brings output as
PLANNED UNPLANNED AVERAGE
25 6 4
The value in AVERAGE is incorrect it should display 4.16 instead of 4. I'm not sure what is the mistake.
25 / 6 equals 4⅙ it does not equal 4.16 unless you are explicitly rounding down the result to two decimal places.
For the most flexibility and precision when using decimal numbers in Db2 you could consider using use DECFLOAT. For example
$ db2 "values 25::decfloat/6"
1
------------------------------------------
4.166666666666666666666666666666667
When rounding DEFFLOAT values, Db2 uses the values of the CURRENT DECFLOAT ROUNDING MODE special register to determine the rounding mode. This defaults to ROUND_HALF_EVEN (and is the only values allowed in some Db2 configurations).
db2 "values ROUND(25::decfloat/6,2)"
1
------------------------------------------
4.17
1 record(s) selected.
to truncate (i.e. round down) then you can use DECIMAL and FLOATs as Mao suggested, or to avoid issues with binary floating points, just DECIMALs
$ db2 "values DECIMAL(25::DECIMAL/6,7,2)"
1
---------
4.16
1 record(s) selected.
You can use something like: CAST( float(x.planned)/float(y.unplanned) AS DECIMAL(9,2) ) as average to explicitly control the result precision and scale

How to round off numbers in SQL Server database

I have a column (named PercentageDifference) with numbers that have decimal places as shown below:
PercentageDifference
1.886792452830100
2.325581395348800
2.758620689655100
-3.689320388349500
-0.284900284900200
0.400000000000000
I want a query to round off the numbers to the nearest 10 and then leave 2 decimal places.
Here is the output am looking for:
PercentageDifference
1.89
2.33
2.76
-3.69
-0.28
0.40
I have tried to use the ROUND function but its not giving me the expected results:
select round([Percentage Difference], 2, 1) from Table
How can this be achieved?
You need only CAST:
SELECT CAST([Percentage Difference] AS decimal(19,2)) FROM Table;

Trim a decimal to 2 places Bigquery

I am currently running a query that runs a sum function and also divides this number. Currently I get values like 0.0904246741698848, and 1.6419814808335567. I want these decimals to be trimmed to 2 spaces past the decimal point. Their schema is a float. Here is my code. Thanks for the help.
#standardSQL
SELECT
Serial,
MAX(createdAt) AS Latest_Use,
SUM(ConnectionTime/3600) as Total_Hours,
COUNT(DISTINCT DeviceID) AS Devices_Connected
FROM `dataworks-356fa.FirebaseArchive.Firebase_ConnectionInfo`
WHERE PeripheralType = 1 or PeripheralType = 2 or PeripheralType = 12
GROUP BY Serial
ORDER BY Latest_Use DESC
#standardSQL
WITH `data` AS (
SELECT 0.0904246741698848 AS val UNION ALL
SELECT 1.6419814808335567
)
SELECT val, ROUND(val, 2) AS rounded_val
FROM `data`
for example, assuming your want apply this to your Total_Hours column :
#standardSQL
SELECT
Serial,
MAX(createdAt) AS Latest_Use,
ROUND(SUM(ConnectionTime/3600),2) AS Total_Hours,
COUNT(DISTINCT DeviceID) AS Devices_Connected
FROM `dataworks-356fa.FirebaseArchive.Firebase_ConnectionInfo`
WHERE PeripheralType = 1 OR PeripheralType = 2 OR PeripheralType = 12
GROUP BY Serial
ORDER BY Latest_Use DESC
I found that rounding was problematic if my data had a whole number such as 2.00 and I needed all of my data to reflect 2 decimal places as these were for prices that end up getting displayed. Big Query was returning 2.0 no matter what I specified to round to using ROUND.
Assuming you're working with data that never surpasses 2 decimal places, and it is stored as a STRING, this code will work (if it's more decimal places, add another 0 to the addition for each space).
FORMAT("%.*f",2,CAST(GROSS_SALES_AMT AS FLOAT64) + .0001)
This will take a float in BigQuery and format it with two decimal points.
CAST(SUM(ConnectionTime/3600) AS STRING FORMAT '999,999.99')
Note: Add a a currency symbol (e.g., $) for currency ($999,999.99).
Example:
You can always use the round() function.
If you are looking for precision after decimal (as using round will round-off the values) you can use substr(str(value),precision) which will give exact output after decimal.

Retrospection on Float, Real and Decimal data types

I'm trying to understand the repercussions of having a column with real data type in a database(Sql Server) table, in my scenario. I have a column in my database with real datatype. The data is static, its always one of the values in range 0.0, 0.1, 0.2.. to 1.0.
Use Case:
I have to Sum up the values in the column and use the sum value in some arithmetic calculations which include financial data.
Concern?:
When I sum up values in the column it gives me result with more decimal places.
Test:
I want sum up the column values and use it in multiplication and division calculations.
I want to repeat #1 for same set of values in a column with decimal and float data types.
Procedure: I have created three different tables with a single column and same set of values but different data types, one with decimal, float and real. And perform the arithmetic calculations on each of them.
CREATE TABLE #tReal(d real);
INSERT INTO #tReal
SELECT 0.1 UNION ALL
SELECT 1 UNION ALL
SELECT 1 UNION ALL
SELECT 0.9 UNION ALL
SELECT 1 UNION ALL
SELECT 0.9 UNION ALL
SELECT 1;
select SUM(d) from #tReal
Expected Result : 5.9
Actual Result : 5.8999999538064
And, If I perform round operation on the sum the result is as expected
declare #sumofd real
select #sumofd = SUM(d) from #tReal
select round(#sumofd , 1)
Result: 5.9
Also, if I update datatype from real to float
CREATE TABLE #tfloat(d float);
INSERT INTO #tfloat
SELECT 0.1 UNION ALL
SELECT 1 UNION ALL
SELECT 1 UNION ALL
SELECT 0.9 UNION ALL
SELECT 1 UNION ALL
SELECT 0.9 UNION ALL
SELECT 1;
select SUM(d) from #tfloat
Expected Result : 5.9
Actual Result : 5.9
And, This is the same case if I update datatype from real to decimal
CREATE TABLE #tDecimal(d DECIMAL(3,2));
INSERT INTO #tDecimal
SELECT 0.1 UNION ALL
SELECT 1 UNION ALL
SELECT 1 UNION ALL
SELECT 0.9 UNION ALL
SELECT 1 UNION ALL
SELECT 0.9 UNION ALL
SELECT 1;
select SUM(d) from #tDecimal
Expected Result : 5.94
Actual Result : 5.94
And, If I perform some basic arithmetic operations on the sum, without rounding, like
declare #sumofdReal real
declare #sumofdFloat float
declare #sumofdDecimal decimal(3,2)
select #sumofdReal = SUM(d) from #tReal
select #sumofdFloat = SUM(d) from #tfloat
select #sumofdDecimal = SUM(d) from #tDecimal
Multiplication:
select #sumofdReal * 2
Result: 11.8
select #sumofdFloat * 2
Result: 11.8
select #sumofdDecimal * 2
Result: 11.88
Division:
select #sumofdReal / 2
Result: 2.95
select #sumofdFloat / 2
Result: 2.95
select #sumofdDecimal / 2
Result: 2.97000
Drop Tables:
drop table #tReal
drop table #tfloat
drop table #tDecimal
Following are my questions
In my scenario, having a datatype as real will have any repercussions?
If #1 is yes, what kind of repercussions? Do I have to change datatype to float or decimal? Why?
If #1 is No, Why? Please explain?
Is there a point to which float and real types can produce exact result and anything beyond it rounding errors will show up?
real in SQL Server is a synonym for float(24), which takes 4 bytes and up to 7 digits of precision.
float by itself is the same as float(53) which is also the same as double which takes up 8 bytes and has up to 15 digits of precision.
In my scenario, having a datatype as real will have any repercussions?
Possibly. decimal, float, and real have different characteristics and are not fully interchangeable. If you want to maintain the exact decimal representation, use the decimal datatype with the appropriate scale and precision. If your numbers represent imprecise data (such as temperature, height, time, or other "natural" measurements that cannot be measured without some imprecision) and want faster mathematical operations then use float (or real if you don;t need more than 7 digits of precision.
When I sum up values in the column it gives me result with more decimal places.
When you add floating point numbers, SQL determines how big the result can be and will use the appropriate data type. When you add two reals, the result could have more than 7 digits of precision, so it may use float as the resulting data type.
Do I have to change datatype to float or decimal? Why?
Use float if you may have more than 7 digits of precision, don't need absolute precision from a decimal standpoint, and want to use a floating-point type for faster calculations.
If you want a fixed scale and precision and want to minimize the imprecision involved with floating point numbers use decimal.
Working with floating-point values always has repercussions, because they are not represented exactly and some rounding errors will always occur. You have to be most careful when comparing values with constants, e.g. if (a == 0.0) as this won't always work if 'a' is the result of mathematical operations. Float and Decimal just give you different ranges and precisions.
If you are using these values in financial calculations, then you should always (pretty much) use decimal types, otherwise you will run into issues with floating point rounding at some point. People get very wound up when you start losing pennies.
You may want to read some more on floating point arithmetic here:
http://floating-point-gui.de/
Decimal types will not be subject to these and should be exact.
For an example, you will eventually run into the situation where you try and round a number to 2 DP, e.g. 0.695, which you would expect to round up to 0.70.
DECLARE #x REAL = 0.695
SELECT ROUND(#x, 2)
-- outputs 0.69
DECLARE #y DECIMAL(6,4) = 0.695
SELECT ROUND(#y, 2)
-- outputs 0.7000
This is down to the fact that you cannot accurately represent 0.695 as a floating point number and it is in fact marginally less than 0.695 as saved.