sql with rounding issue - sql

I have a problem with sql(maths).
I have a total payable given to vendor which is 33.333, and I need to divide the amount with two users. So I have select
select (16.666 * 2) from dual which gives me 33.332 that is .1 less than the total amount I have to give.
If I have this sql
select (16.667 * 2) from dual, then it gives me 33.334 which .1 greater than 33.333.
How can I divide the total amount which I could equally distribute?
Thanks

I'm not sure from where are you executing your query, but it works here (SQLDeveloper, 10g):
SELECT (33.333 / 2) FROM dual;
16,6665
SELECT (16.6665 * 2) FROM dual;
33,333

Do it the other way around:
select 33.333/2

You are most likely working with the wrong column type. You should be using DECIMAL instead of e.g. FLOAT.
Here is a good summary: http://lists.mysql.com/mysql/189592
Depending on the SQL standard you are using the type can be MONEY, DECIMAL or NUMBER.

Related

DB2 - Arithmetic calculations and rounding

Considering the taxable amount (rateable), the number of days and the rate, I must calculate the interest applied (with the compound rate formula) but I have a problem with floating-point and rounding applied by DB2 V12 (Z/OS).
(Note: The same statement on DB2 LUW does not give me problems)
The value of the interest that I expect is 17,84€ instead I get 17,86€
I'm using this statement:
SELECT CAST(CAST(RATEABLE AS DECFLOAT)
* ( 1 - ( POWER ( ( 1 + CAST(RATE AS DECFLOAT) / 100 ),
( -1 * CAST(NUMBER_DAYS AS DECFLOAT) / CAST(DIVISOR AS DECFLOAT) )
)
)
) AS DECIMAL(18, 2)
) AS PAYMENT_INTEREST
FROM (
--- I simulate accessing my DB2 table.
SELECT CAST(92247.38 AS DECIMAL(18, 2)) AS RATEABLE,
CAST(0.249000 AS DECIMAL(12, 6)) AS RATE,
INTEGER(28) AS NUMBER_DAYS,
INTEGER(360) AS DIVISOR
FROM SYSIBM.SYSDUMMY1
) AS TEMP
If I defined the "RATE" field as DEC (12,3) the calculation is correct but obviously I would not be able to manage more rates with more decimals.
Now, what am I missing here?
Thanks.
Don’t use float datatypes as they will give you this issue. Just define your fields as decimals with enough decimal points to hold the data that you need them to hold. You can always round them in your queries if you need show them with reduced precision

Is it possible to get up to 3 decimal places in Float in PostgreSQL?

I have a table in PostgreSQL, that have a Float column. In my select I use AVG() on that column, so often it gives a number with many decimals. Is there any way to retrict the number of decimals to a maximum of 3, meaning there can be less but not more than 3.
This is the Query:
SELECT team, AVG(score) FROM team_score_table GROUP BY team
You can use round():
select round(val::numeric, 3)
You can also convert to a numeric, but you need a precision appropriate for your values:
select val::numeric(20, 3)
I actually prefer the explicit cast() because it sets the data type of the column to a numeric with an explicit scale -- so downstream apps are aware of the number of decimal places intended in the result.
round() returns a numeric value but it is a "generic" numeric, with no specified scale and precision.
You can see the difference in this example.
You can use a several functions to do that:
SELECT round(42.43666, 2) -- 42.44
SELECT trunc(42.43666, 2) -- 42.43
or cast:
SELECT cast(42.43666 as numeric(20, 2)) -- 42.44
according to your example should be:
SELECT team, round(AVG(score)::numeric, 2) FROM team_score_table GROUP BY team
SELECT team, trunc(AVG(score)::numeric, 2) FROM team_score_table GROUP BY team
SELECT team, cast(AVG(score) as numeric(20,2)) FROM team_score_table GROUP BY team

SQL - 1. Round the difference to 2 decimal places

I am trying to create an SQL statement with a subquery in the SELECT attribute list to show the product id, the current price and the difference between the current price and the overall average.
I know that using the ROUND function will round the difference to zero decimals but I want to round the difference to 2 decimal places.
SELECT p_code, p_price, ROUND(p_price - (SELECT AVG(p_price) FROM product)) AS "Difference"
FROM product;
I tried using CAST but it still gave me the same output.
SELECT p_code, p_price, CAST(ROUND(p_price - (SELECT AVG(p_price) FROM Lab6_Product)) as numeric(10,2)) AS "Difference"
FROM lab6_product;
Thank you in advance for your time and help!
round() takes a second argument:
SELECT p_code, p_price,
ROUND(p_price - AVG(p_price) OVER (), 2) AS "Difference"
FROM product;
Note that I also changed the subquery to a window function.
I often recommend converting to a number or decimal/numeric) instead:
SELECT p_code, p_price,
cast(p_price - AVG(p_price) OVER () as number(10, 2)) AS "Difference"
FROM product;
This ensures that the two decimal points are displayed as well.

SQL decimal places within a select statement

I've been reading threads and seeing the 'Convert' and 'Cast' commands, but I cannot get any to fit in this simple select statement. Very frustrating to have to ask a question this simple, but I cannot find anything that works. Below is the code, and I need the 'discount amount/price' to show up with 2 decimal places. Thank you in advance.
select product_name, list_price, discount_percent, list_price *
(discount_percent*.01) as 'discount_amount',
list_price - (list_price * (discount_percent*.01)) as 'discount_price'
from products
order by discount_price desc
limit 5;
The database should give you back a decimal/numeric type that is capable of storing the fractional digits, but the results grid and/or your application is still responsible for how to display those digits.
Your query looks like it does implicit casting, but you can explicitly do it like this:
select
product_name, list_price, discount_percent, list_price *
(cast(discount_percent as decimal(18,2)) * .01) as 'discount_amount',
cast(list_price as decimal(18,2)) - (cast(list_price as decimal(18,2)) * (cast(discount_percent as decimal(18,2)) * .01)) as 'discount_price'
from products
order by discount_price desc
limit 5;
Your displayed query results might still do its own rounding and display, for example "5" instead of "5.00", but that is because your UI still needs to implement it's own logic to display whatever format you're looking for.
In MySQL, you can use round or truncate:
SELECT ROUND(12.545, 2)
SELECT TRUNCATE(12.545, 2)
in MS SQL, you can Convert:
SELECT CONVERT(DECIMAL(10,2), ColumName) FROM TableName

Select Query: To Show Average of Columns in Decimal

I want to get value in decimal while calculating averave of column values in select query. For that I have used below query. But the value comes as 3.0 instead of 3.6. Is there any solution for that?
SELECT P.ANSW_ONE,P.ANSW_TWO,P.ANSW_THREE,P.ANSW_FOUR,P.ANSW_FIVE,
CAST(((P.ANSW_ONE+P.ANSW_TWO+P.ANSW_THREE+P.ANSW_FOUR+P.ANSW_FIVE)/5) AS DECIMAL(10,1)) AS ANSW_AVG
FROM FEEDBACK P
CAST the whole SUM instead of the result and use 5.0 just to force it to be decimal instead of integer.
SELECT P.ANSW_ONE,
P.ANSW_TWO,
P.ANSW_THREE,
P.ANSW_FOUR,
P.ANSW_FIVE,
(CAST((P.ANSW_ONE+P.ANSW_TWO+P.ANSW_THREE+P.ANSW_FOUR+P.ANSW_FIVE) DECIMAL(10,1) /5.0)) AS ANSW_AVG
FROM FEEDBACK P
Try This
SELECT
P.ANSW_ONE,
P.ANSW_TWO,
P.ANSW_THREE,
P.ANSW_FOUR,
P.ANSW_FIVE,
CAST(CAST(P.ANSW_ONE+P.ANSW_TWO+P.ANSW_THREE+P.ANSW_FOUR+P.ANSW_FIVE AS DECIMAL(10,1))/5 AS DECIMAL(10,1)) AS ANSW_AVG
FROM FEEDBACK P
Cast the sum before dividing by 5 and then again cast the result