Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calculating Percentages in Postgres

I'm completely new to PostgreSQL. I have the following table called my_table:

a    b    c        date
1    0    good     2019-05-02
0    1    good     2019-05-02
1    1    bad      2019-05-02
1    1    good     2019-05-02
1    0    bad      2019-05-01
0    1    good     2019-05-01
1    1    bad      2019-05-01
0    0    bad      2019-05-01

I want to calculate the percentage of 'good' from column c for each date. I know how to get the number of 'good':

SELECT COUNT(c), date FROM my_table WHERE c != 'bad' GROUP BY date;

That returns:

count    date
3        2019-05-02
1        2019-05-01

My goal is to get this:

date         perc_good
2019-05-02   25
2019-05-01   75

So I tried the following:

SELECT date, 
       (SELECT COUNT(c) 
        FROM my_table 
        WHERE c != 'bad' 
        GROUP BY date) / COUNT(c) * 100 as perc_good 
FROM my_table 
GROUP BY date;

And I get an error saying

more than one row returned by a subquery used as an expression.

I found this answer but not sure how to or if it applies to my case:

Calculating percentage in PostgreSql

How do I go about calculating the percentage for multiple rows?

like image 939
vw999 Avatar asked Mar 03 '23 22:03

vw999


2 Answers

avg() is convenient for this purpose:

select date,
       avg( (c = 'good')::int ) * 100 as percent_good
from t
group by date
order by date;

How does this work? c = 'good' is a boolean expression. The ::int converts it to a number, with 1 for true and 0 for false. The average is then the average of a bunch of 1s and 0s -- and is the ratio of the true values.

like image 112
Gordon Linoff Avatar answered Mar 11 '23 22:03

Gordon Linoff


For this case you need to use conditional AVG():

SELECT 
  date, 
  100 * avg(case when c = 'good' then 1 else 0 end) perc_good 
FROM my_table 
GROUP BY date;

See the demo.

like image 28
forpas Avatar answered Mar 11 '23 20:03

forpas