计算Postgres中的百分比

时间:2019-05-29 16:07:33

标签: sql postgresql group-by

我对PostgreSQL完全陌生。我有一个名为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

我想计算每个日期c列中“好”的百分比。我知道如何获得“好”的数字:

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

返回:

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

我的目标是得到这个:

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

所以我尝试了以下操作:

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;

我收到一条错误消息

  

由子查询返回的多于一行用作表达式。

我找到了这个答案,但不确定如何或是否适用于我的情况:

Calculating percentage in PostgreSql

如何计算多行的百分比?

3 个答案:

答案 0 :(得分:2)

avg()为此目的很方便:

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

这是如何工作的? c = 'good'是布尔表达式。 ::int将其转换为数字,其中1表示true,0表示false。那么平均值就是一串1和0的平均值-就是真实值的比率。

答案 1 :(得分:1)

您可以使用条件和来获得良好的价值,并计算总数

精美代码示例

  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 

以及您的结果

  select  date
    , (sum(case when c='good' then 1 else 0 end) / count(c))* 100 perc_good
  from my_table
  group by  date 

或a_horse_with_no_name使用count(*)filter()所建议的

select  date
  , ((count(*) filter(where c='good'))/count(*))* 100 perc_good
from my_table
group by  date 

答案 2 :(得分:1)

在这种情况下,您需要使用条件AVG()

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

请参见demo