Reputation: 1081
I'm trying to find how to calculate a new SQL column that works on a formula involving 'NA' values. I think that I am not getting my desired result because of either the 'NA' values or because of my grouping. Please see the table and formula below:
My table is the following:
website session score
google 1 1
google 2 NA
bbc 3 2
bbc 4 4
bbc 5 5
The formula i am using to created a new calculated field is the following:
select
website,
(sum(score IN (4,5))/sum((score is not null)) - sum(score IN (1,2))/sum(score is not null))*100 as new_column
from
my_table
group by
website
Essentially the formula is trying to do the following:
Sum up those values in the score column that are either 4 or 5, then divide them by the sum of the numbers in the score column that do exist.
Then deduct the following:
Sum up those values in the score column that are either 1 or 2, then divide them by the sum of the numbers in the score column that do exist.
Finally:
Multiply the entire output by 100
The formula has to be applied to each group.
So you should have the following desired result:
Taking only the first group of "google"
You have 4 not null values. you have 2 values whereby the value is IN (1,2) and 0 values in (4,5).
so you would have the following formula:
((0/4)-(2/4))*100
-2/4 * 100
= -50
however, when calculating this in SQL i recieve the value -100. which does not make sense to me. can anyone help?
Upvotes: 0
Views: 112
Reputation: 5803
I think you are looking for a difference between percentage of (4,5) and (1,2) for each group. Since null values are ignored in aggregation, you could simply do
(avg(score in (4,5)) - avg(score in (1,2)))*100
Upvotes: 1
Reputation: 639
I advise multiplying by 1.0 each sum so that it doesn't round the sum to int value which would result in zero(0) for 'bbc' group.
Here is the updated version of your query(Check also SQL fiddle http://sqlfiddle.com/#!5/5fca1/8):
select website,
(sum(score IN (4,5)) * 1.0/sum(score is not null) - sum(score IN (1,2)) * 1.0/sum(score is not null))*100.0 as new_column
from my_table
group by website
Upvotes: 1
Reputation: 13509
From your manual example, You may first sum all the not null values, and then use that value in your code -
WITH NN_SUM AS (SELECT SUM(score is not null) NOT_NULL_SUM
FROM my_table)
SELECT website,
(((sum(score IN (4,5)) - sum(score IN (1,2))) / NOT_NULL_SUM) * 100 as new_column
FROM my_table
CROSS JOIN NN_SUM
GROUP BY website;
Upvotes: -1
Reputation: 2306
You have one not null values for Google. The sum of it is one. So your formula is resulting in (0-1/1)*100 which is -100, which is what it is giving.
What I think you want is the count of all Google records divided by the count of all non-null records?
Upvotes: 2