Maths Issue in SQL Server [duplicate] - sql

This question already has answers here:
Dividing 2 numbers returns 0 [duplicate]
(3 answers)
How to calculate percentage with a SQL statement
(13 answers)
Division of integers returns 0
(2 answers)
Closed 3 years ago.
I am trying to perform a maths equation in SQL to calculate service up time. I have a column with pass counts and a column with fail counts.
I have achieved this sum in VB for the application side and the sum is as follows: pass / (pass+fail) * 100.
The results should be on some rows 99.98 but I can't get SQL to give me the same result. I either get 100 or 0 as the result.
This is my SQL query:
select pass / sum(pass+fail) * 100 as total, friendlyname from sensors group by pass, friendlyname
Example row:
Friendly Name | Pass | Fail
_____________________________
Cloudflare | 25527 | 23
So as you can see the result should be 99.90 when done on a calculator using above formula but SQL reports this sum as 0.
Really would be grateful for some help!

Make at least one portion of the division a floating point number, to force that precision. Also, your math seems to be off. If you want to compute the ratio of passes/fails to the total counts, then sums should appear in both the numerator and denominator.
select
100.0 * sum(pass) / sum(pass+fail) as pass_pct,
100.0 * sum(fail) / sum(pass+fail) as fail_pct
friendlyname
from sensors
group by
friendlyname;

Try this :
select
(pass * 100.0) / sum(pass+fail) as total,
friendlyname
from sensors
group by friendlyname, pass

Related

Calculating Column value based on row above and previous column [duplicate]

This question already has answers here:
How to calculate Running Multiplication
(4 answers)
Closed 6 months ago.
I have a table I'm trying to create that has a column that needs to be calculated based on the row above it multiplied by the previous column. The first row is defaulted to 100,000 and the rest of the rows would be calculated off of that. Here's an example:
Age
Population
Deaths
DeathRate
DeathPro
DeathProb
SurvivalProb
PersonsAlive
0
1742
0
0
0.1
0
1
100,000
51
2048
1
0.00048
0.5
0.00048
0.99951
99951.18379
52
1921
0
0
0.5
0
1
99951.18379
61
1965
1
0.00051
0.5
0.00051
0.99949
99900.33
I skipped some ages so I didn't have type it all in there, but the ages go from 0 - 85. This was orginally done in excel and the formula for PersonsAlive (which is what I'm trying to recreate) was G3*H2 aka previous value of PersonsAlive * Survival Probability.
I was thinking I could accomplish this with the lag function, but with the example I provided above, I get null values for everything after age 1 because there is no value in the previous row. What I want to happen is that PersonsAlive returns 100,000 until I get a death (in the example at Age 51) and then it does the calculation and returns the value (99951) until another death happens (Age 61). Here's my code, which includes two extra columns, ZipCode (the reason we want to do it in SQL is so we can calculate all zips at once) and PersonsAliveTemp, which I used to set Age 0 to 100,000:
SELECT
ZipCode
,Age
,[Population]
,Deaths
,DeathRate
,Death_Proportion
,DeathProbablity
,SurvivalProbablity
,PersonsAliveTemp
,(LAG(PersonsAliveTemp,1) OVER(PARTITION BY ZipCode ORDER BY Age))*SurvivalProbablity as PersonsAlive
FROM #temp4
I also tried it with defaulting PersonsAliveTemp to 100,000 and 0, which "works" but doesn't do the running calculation.
Is it possible to get the lag function (or some other function) to do a running row by row calc?
This converts a running product into an addition via logarithms.
select *,
100000 * exp(sum(log(SurvivalProb)) over
(partition by ZipCode order by Age
rows between unbounded preceding and current row)
) as PersonsAlive
from data
order by Age;
https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=36be4d66260c74196f7d36833018682a

How to express percentage with decimal in SQL [duplicate]

This question already has answers here:
SQL Server, division returns zero
(6 answers)
Closed 1 year ago.
SELECT RecruitmentSource, COUNT(RecruitmentSource) AS NumberOfHired, COUNT(RecruitmentSource)/SUM(COUNT(RecruitmentSource)) OVER () AS PercentageHired
FROM HRDataset_v14$
GROUP BY RecruitmentSource
Percentage Hired that I expect as below link
FYI, Total Number of Hired is 311 so I expect the number would be like
1. 0.0739
2. 0.0932
3. 0.0997
.
.
.
9. 0.0418
Please help me to solve it.
SQL Server does integer division. I usually just multiply by 1.0 to avoid this:
SELECT RecruitmentSource, COUNT(RecruitmentSource) AS NumberOfHired,
COUNT(RecruitmentSource) * 1.0/SUM(COUNT(RecruitmentSource)) OVER () AS PercentageHired
FROM HRDataset_v14$
GROUP BY RecruitmentSource

Getting percentage of each value in a row [duplicate]

This question already has answers here:
How to get a float result by dividing two integer values using T-SQL?
(10 answers)
Closed 4 years ago.
I have a pretty simple breakdown of Customer names, and a corresponding count of that name. What I need is a third column which gives the percent of customers with that name.
Here's an example of what I need:
|NAME| |NAME_COUNT| |NAME_PERCENT|
Bob 5 41.7
John 4 33.3
Toby 3 25.0
I have the first two fields, but can't seem to nail down the percent.
The final part of my query looks like this:
SELECT
a.Name
a.Name_Count
FROM #NameTemp a
GROUP BY
a.Name,
a.Name_Count
ORDER BY
a.Name_Count DESC
I would think this would work in the select statement to get the percentage of each row, but it doesn't. It just gives me a value of 1 for every row in the Percent field:
a.Name_Count/SUM(a.NameCount) AS "Percent"
Just use window functions:
select name, name_count, name_count * 1.0 / sum(name_count) over ()
from #nametemp;
Note the * 1.0. SQL Server does integer division, so you need to convert to a format that has a decimal place.
I am guessing that you have an original table that is unaggregated. If so, doing this all in one query without a temporary table is a better solution:
select name, count(*) as name_count, count(*) * 1.0 / sum(count(*)) over ()
from names
group by name;

Redshift division result does not include decimals

I'm trying to do something really quite basic to calculate a kind of percentage between two columns in Redshift. However, when I run the query with an example the result is simply zero because the decimals are not being covered.
code:
select 1701 / 84936;
Output:
I tried :
select cast(1701 / 84936 as numeric (10,10));
but the result was 0.0000000000.
How could I solve this silly thing?
It is integer division. Make sure that at least one argument is: NUMERIC(accurate data type)/FLOAT(caution: it's approximate data type):
/ division (integer division truncates the result)
select 1701.0 / 84936;
-- or
SELECT 1.0 * 1701 / 84936;
-- or
SELECT CAST(1701 AS NUMERIC(10,4))/84936;
DBFiddle Demo
When mixing data types the order counts
Note that the order of the elements in a math expression counts for the data type of the result.
Let's assume that we intend to calculate the percentage unit_sales/total_sales where both columns (or numbers) are integers.
See and try with this code here.
-- Some dummy table
drop table if exists sales;
create table sales as
select 3 as unit_sales, 9 as total_sales;
-- The calculations
select
unit_sales/total_sales*100, --> 0 (integer)
unit_sales/total_sales*100.0, --> 0.0 (float)
100.0*unit_sales/total_sales --> 33.3 (float and expected result)
from sales;
The output
0 | 0.0 | 33.33
The first column is 0 (integer) because of 3/9=0 in an integer division.
The second column is 0.0 because SQL first got the integer 0 (3/9), and later, SQL converts it to float in order to perform the multiplication by 100.0.
The expected result.
The non-integer 100.0 at the beginning of the expression force a non-integer calculation.

Round value only if it is greater than 5 [duplicate]

This question already has answers here:
Sql Round, when on .5, rounds to the greater number ie 1.235 result 1.24 [duplicate]
(2 answers)
Closed 5 years ago.
I'm not sure that this is a duplicate question.
I need to ROUND a value only if the succeeding value is greater than 5.
For example:
If i have 123.4575, then the rounded value should be 123.457.
If i have 123.4576, then the rounded value should be 123.458.
But the default ROUND is not working as i'm expecting. See the below query,
select cast(round(123.4575, 3) as decimal(18,3))
Result:
123.458 (where it needs to be 123.457)
I need only three decimal points.
I prefer to suggest me some in-built functions rather than writing functions on my own.
Thanks.
This has been asked (many times). 5 is always rounded up by SQL Server. If you do not want to write your own routine look at Minh's answer here. This shows a neat trick to achieve what you want using a case statement and FLOOR.
Also an easy alternative is to subtract 1 from your number first at a precision 1 greater than your rounding, thus:
SELECT CAST(ROUND(123.4575 - 0.00001, 3) as decimal(18,3))
gives 123.457, whilst
SELECT CAST(ROUND(123.4576 - 0.00001, 3) as decimal(18,3))
gives 123.458