I have a query like this:
Select Customer,JobType,sum(SThours),
sum(OThours),SortMonth,
str((sum(OThours)/sum(SThours)),5,2)AS Ratios
from #data
group by Customer,JobType,SortMonth
Sum (SThours): 688
sum(OThours): 618
The ratio should be 618/688=0.90 but my result is 1.00
I am new to SQL, and I need help. Thanks.
Try casting one or other side of the division to a float - to force floating point rather than integer division.
SELECT
Customer,
JobType,
sum(SThours),
sum(OThours),
SortMonth,
str((CAST(sum(OThours) AS FLOAT)/sum(SThours)),5,2) AS Ratios
FROM
#data
GROUP BY
Customer,
JobType,
SortMonth
Try casting the number to decimal
SELECT
Customer,
JobType,
sum(SThours),
sum(OThours),
SortMonth,
str((CAST(sum(OThours) AS DECIMAL)/sum(SThours) ),5,2) AS Ratios
FROM
#data
GROUP BY
Customer, JobType, SortMonth
Try this sample fiddle
it is simple example showing getting decimal values
Your problem is that you're performing an integer division, which will always result in an integer value in return.
You should cast the sums to a floating point numeric value (decimal should work) before dividing them.
Related
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
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.
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.
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
I am working on SQL Server. I have a table that has an int column HalfTimeAwayGoals and I am trying to get the AVG with this code:
select
CAST(AVG(HalfTimeAwayGoals) as decimal(4,2))
from
testtable
where
AwayTeam = 'TeamA'
I get as a result 0.00. But the correct result should be 0.55.
Do you have any idea what is going wrong ?
select
AVG(CAST(HalfTimeAwayGoals as decimal(4,2)))
from
testtable
where
AwayTeam = 'TeamA'
If the field HalfTimeAwayGoals is an integer, then the avg function does an integer average. That is, the result is 0 or 1, but cannot be in between.
The solution is to convert the value to a number. I often do this just by multiplying by 1.0:
select CAST(AVG(HalfTimeAwayGoals * 1.0) as decimal(4, 2))
from testtable
where AwayTeam = 'TeamA';
Note that if you do the conversion to a decimal before the average, the result will not necessary have a scale of 4 and a precision of 2.
Can you try dividing by 1.00 to convert the integer into decimal?
select
AVG(HalfTimeAwayGoals/1.00) as average
from
testtable
where
AwayTeam = 'TeamA'
I used the /1.00 OR /1.0000 trick on various databases to do the job. Unfortunately, I don't have access MS-SQL to try it. The division of integer by 1.00 will change the integer to decimal.
SELECT AVG(integerfield/1.00) FROM table
In MySQL
SELECT AVG(integerfield) FROM table
gives me 4 decimal points.
If I do
SELECT AVG(integerfield/1.00) FROM table
I get 8 decimal points.