[英]Calculating Percentages in Postgres
I'm completely new to PostgreSQL. 我是PostgreSQL的新手。 I have the following table called my_table: 我有一个名为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. 我想为每个日期计算出c列中“良好”的百分比。 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 在PostgreSQL中计算百分比
How do I go about calculating the percentage for multiple rows? 如何计算多行的百分比?
avg()
is convenient for this purpose: avg()
可以方便地实现此目的:
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. c = 'good'
是一个布尔表达式。 The ::int
converts it to a number, with 1 for true and 0 for false. ::int
将其转换为数字,其中1表示true,0表示false。 The average is then the average of a bunch of 1s and 0s -- and is the ratio of the true values. 那么平均值就是一串1和0的平均值-是真实值的比率。
You could use a conditional sum for get the good value and count for total 您可以使用条件和来获得良好的价值,并计算总数
below an exaustive code sample 精美代码示例下方
select date
, count(c) total
, sum(case when c='good' then 1 else 0 end) total_good
, sum(case when c='bad' then 1 else 0 end) total_bad
, (sum(case when c='good' then 1 else 0 end) / count(c))* 100 perc_good
, (sum(case when c='bad' then 1 else 0 end) / count(c))* 100 perc_bad
from my_table
group by date
and for your result 为了你的结果
select date
, (sum(case when c='good' then 1 else 0 end) / count(c))* 100 perc_good
from my_table
group by date
or as suggested by a_horse_with_no_name using count(*) filter() 或如a_horse_with_no_name所建议使用count(*)filter()
select date
, ((count(*) filter(where c='good'))/count(*))* 100 perc_good
from my_table
group by date
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.