SQL - 1. Round the difference to 2 decimal places - sql

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.

Related

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

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.

How to get ceil value with custom digit number in SQLite?

In my database, I have prices of items, and the discount percents for the items.
Here is a sample row from the database
Name Price DiscountPercent
**** 1000.26 17.00
Now for this row I need to get the discounted price, but with two digits after the comma, i.e. for the discounted price 830.2158 I want to get 830.21
Doing
Round((UnitPrice - (UnitPrice * DiscountPercent)/100),2)
in my select query will return 830.22 which is not what I want. I could have achieved the desired result if I could do
Round(Floor((UnitPrice - (UnitPrice * DiscountPercent)/100) * 100)/100,2)
but unfortunately there is no Floor function in SQLite.
I also tried to cast to int and then divide by 100 and Round, but it seems that SQLite casts the whole result to int, because I get 830.0
How can I do this?
Thanks in advance
Ok this one is complicated and it is basically subtracting off the 3rd decimal place.
round((UnitPrice - (UnitPrice * DiscountPercent)/100)-(((UnitPrice - (UnitPrice * DiscountPercent)/100)%1*100)%1/100),2)
Easier to read and to get the basic Idea:
round(value -((value%1*100)%1/100),2)
SELECT cast(cast((UnitPrice - UnitPrice * DiscountPercent/100) * 100 as int) as real) / 100 FROM Product

Calculate weighted average in single query

Example data:
table A
part rating numReviews
A308 100 7
A308 98 89
I'm trying to get the average rating for the above data.
What it needs to be is the sum of rating*numReviews for each line divided by the total numReviews
This is what I'm trying but it's giving incorrect result (49.07, should be 98.15):
select part,
cast((AVG(rating*numReviews)/sum(numReviews)) as decimal(8,2)) as rating_average
from A group by part order by part
Can this be done in a single query? I'm using SQL Server
Just go back to the definition of weighted average, so use sum()s and division:
select part, sum(rating * numreviews) / sum(numreviews) as rating_average
from a
group by part
order by part;
You can convert this to a decimal if you like:
select part,
cast(sum(rating * numreviews) / sum(numreviews) as decimal(8, 2)) as rating_average
from a
group by part
order by part;

sql with rounding issue

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.