Sum column only 2 digits after precision (no round) - sql

I have a float type column with numbers that have 6 digits after precision. I want to sum the column only by 2 digits after precision.
For example, I have 1.257868 and 1.258778 as values and I want to get the result of 2.50 as result of sum.

It looks like you want something like:
sum(floor(mycol * 100) / 100)
The expression within the sum() performs the truncation to 2 decimals.

You can use the 3 argument form of round():
select sum(round(mycol, 2, 1))

odbc truncate
select v.val, {fn TRUNCATE(v.val, 2)} as trncted, sum({fn TRUNCATE(v.val, 2)}) over() as sumtrncated
from
(values (1.257868), (1.258778)) as v(val);

Related

Why doesn't ROUND(23/6) = 4 in SQL?

Case A: When you are trying to round the result yourself to the nearest decimal
SELECT ROUND (3.833333333333333) -- 4
Case B: When you let SQL do the math and then round to the nearest decimal
SELECT ROUND (23/6) -- 3 (OR CEIL)
In this case according to the order of operations:
SQL will divide what’s between the parenthesis, first = 3.833333333333333
And then (This is the problem) it will erase everything in the decimal places. (Converting it to int, automatically) =3.0
Now, let's round the decimals (Which are already erased in the previous step! And now it’s = 0)
So, the last result will be (3). Not (4).!
Even with conversions:
SELECT CAST (DIV (23,6) AS NUMERIC (10,5)) AS tst -- 3.00000
SELECT CAST ((23/6) AS DECIMAL (5,2)) AS tst -- 3.00
SELECT CAST (23/6 AS FLOAT) AS tst -- 3
SELECT CAST (23/6 AS REAL) AS tst -- 3
Is there a solution to this problem ?
Because it performs integer division. When then engine evaluates:
ROUND (23/6)
the expression 23/6 is evaluated first as 3. Then:
ROUND (3)
is evaluated as 3.
If you want the float precision you can multiply by 1.0. For example by doing:
ROUND ( 1.0 * 23/6)

WHERE condition to exclude amounts with decimals ending with '0's or '5's

Objective:
I have a column 'amount' with decimals. I am trying to exclude rows where the amount value ends either with '0's or '5's.
How can I achieve that...
Column type: decimal (7,2)
Ex: numbers to exclude
10.25
11.20
100.00
You probably want this:
WHERE (CAST(your_field * 100 AS INTEGER) % 5) <> 0
But it is hard to tell without more detail on your data type. Also there can be funky rounding issues with floating point values.
An interesting way to do this uses "modular" arithmetic
where col % 0.1 not in (0.00, 0.05)
The % operator works on non-integer bases as well as integer ones.
What I did here is changed the number into a string, trimmed off the trailing blanks, and then reversed the string to take the first character to see if it was no 1 or 5
SELECT * into #test FROM (SELECT CAST(10.25 as decimal(7,2)) as val UNION SELECT 8.21 UNION SELECT 6.00) DQ
select * from #test WHERE LEFT(REVERSE(RTRIM(CAST(val as nvarchar(50)))),1) NOT IN ('5', '0')
drop table #test

How to get first 4 digits in a number, with oracle sql

I could do
select substr(to_char(20041111), 1, 4) FROM dual;
2004
Is there a way without converting to string first?
You can use the FLOOR function:
select floor(20041111/10000) from dual;
The following does not convert to a string but I'm not sure it's more readable...:
select floor(20041111 / power(10, floor(log(10, 20041111) - 3)))
from dual;
log(10, 20041111) -> 8.3... meaning that 10 ^ 8.3... = 20041111
if you floor this value, you get the number of digits in the base 10 representation of your number
if you want to remove digits, you just need to divide by 10 ^ (#digits - 3) (and not -4 since 10^1 already has 2 digits)
Another approach would be to use REGEXP_REPLACE
SELECT REGEXP_REPLACE(20041111,'....$') FROM dual;

Division ( / ) not giving my answer in postgresql

I have a table software and columns in it as dev_cost, sell_cost. If dev_cost is 16000 and sell_cost is 7500, how do I find the quantity of software to be sold in order to recover the dev_cost?
I have queried as below:
select dev_cost / sell_cost from software ;
It is returning 2 as the answer. But we need to get 3, right?
What would be the query for that?
Your columns have integer types, and integer division truncates the result towards zero. To get an accurate result, you'll need to cast at least one of the values to float or decimal:
select cast(dev_cost as decimal) / sell_cost from software ;
or just:
select dev_cost::decimal / sell_cost from software ;
You can then round the result up to the nearest integer using the ceil() function:
select ceil(dev_cost::decimal / sell_cost) from software ;
(See demo on SQLFiddle.)
You can cast integer type to numeric and use ceil() function to get the desired output
The PostgreSQL ceil function returns the smallest integer value that
is greater than or equal to a number.
SELECT 16000::NUMERIC / 7500 col
,ceil(16000::NUMERIC / 7500)
Result:
col ceil
------------------ ----
2.1333333333333333 3
So your query should be
select ceil(dev_cost::numeric/sell_cost)
from software
You can also cast your variable to the desired type, then apply division:
SELECT (dev_cost::numeric/sell_cost::numeric);
You can round your value , and specify the number of digits after point:
SELECT TRUNC((dev_cost::numeric/sell_cost::numeric),2);
This query will round result to next integer
select round(dev_cost ::decimal / sell_cost + 0.5)

Rounding of the numeric values

I want to round of the values of two columns:
select a.region as "Regions",
a.suminsured,2 as "SumInsured" ,
a.suminsured/b.sum*100 as pct
from (
SELECT region, sum(suminsured) as suminsured
FROM "Exposure_commune" group by region
) a,
(select sum(suminsured) FROM "Exposure_commune") b
I want the suminsured and pct columns to come with 2 decimal places. Can someone tell me what I should do?
You can use directly numeric with two parameters. Second parameter for round decimal.
select sum(column_name::numeric(10,2)) from tablename
Use round() with two parameters, which only works for the data type numeric.
While being at it, your query can be simpler and faster:
SELECT region
, round(sum(suminsured), 2) AS suminsured
, round((sum(suminsured) * 100) / sum(sum(suminsured)) OVER (), 2) AS pct
FROM "Exposure_commune"
GROUP BY 1;
You can use sum() as window function to get the total without additional subquery, which is cheaper. Related:
Postgres window function and group by exception
Multiplying first is typically cheaper and more exact (although that barely matters with numeric).
Data type is not numeric
For data types double precision of real
You can ...
just cast to numeric to use the same function.
multiply by 100, cast to integer and divide by 100.0.
multiply by 100 and use the simple round() and devide by 100.
The simple round() with just one parameter works for floating point types as well.
Demonstrating all three variants:
SELECT region
, round(sum(suminsured), 2) AS suminsured
, (sum(suminsured) * 100)::int / 100.0 AS suminsured2
, round(sum(suminsured) * 100) / 100 AS suminsured3
, round((sum(suminsured) * 100) / sum(sum(suminsured)) OVER (), 2) AS pct
, ((sum(suminsured) * 10000) / sum(sum(suminsured)) OVER ())::int / 100.0 AS pct2
, round((sum(suminsured) * 10000) / sum(sum(suminsured)) OVER ()) / 100 AS pct3
FROM "Exposure_commune"
GROUP BY 1;
SQL Fiddle.