查找相对百分比

Find relative percentage

我有一个用户投票的民意调查。例如:

你想要菲亚特吗?

id | answer
1    yes
2    no 
3    yes
...
25   no

count = 20 yes / 5 no

(20 * 100) /25 = 80% Yes
(5 * 100) /25 = 20% No

所以,80% 的人想要菲亚特,20% 的人不想要。显然我可以做类似的事情:

select answer, count(*) as total from fast_survey group by answer;

但是这会显示计数,我正在寻找相对百分比。知道我该怎么做吗?

怎么样:

SELECT 
    t1.answer, t1.votes / t2.total_votes
FROM
    (SELECT answer, count(*) AS votes FROM fast_survey GROUP BY answer) AS t1,
    (SELECT count(*) AS total_votes FROM fast_survey) AS t2
;

如果您的调查有多个答案,这也适用。

SELECT round(count(*) FILTER (WHERE answer)     * 100.0 / count(*), 2) AS pct_yes
     , round(count(*) FILTER (WHERE NOT answer) * 100.0 / count(*), 2) AS pct_no
FROM   fast_survey;
pct_yes | pct_no
--------+-------
  80.00 |  20.00

db<>fiddle here

我乘以 100.0(不是 100)以避免整数除法。结果是 numeric 类型,可以将其提供给 round() 进行美化。参见:

  • Calculating rates in PostgreSQL

假设 answerboolean。否则,适应。

聚合 FILTER 子句已在 Postgres 9.4 中引入。参见:

  • How can I simplify this game statistics query?

应该尽可能快。

只需将它与 table 一起计算所有记录而不对答案进行划分并计算百分比...类似这样

select answer, count(*) / max(totalCount) * 100 as total from fast_survey group by answer
left join (select count(*) FROM fast_survey as totalCount) as all on true

您可以 COUNT 通过分区获取每种答案类型的值:

SELECT DISTINCT answer,
       COUNT(*) OVER (partition BY answer) AS total,
       COUNT(*) OVER (partition BY answer) * 100 /
       COUNT(*) OVER () AS percentage
FROM fast_survey

Demo on SQLFiddle

如果您希望百分比更精确(对于上述查询,它是一个整数除法),请将第一个 COUNT 转换为 FLOAT:

SELECT DISTINCT answer,
       COUNT(*) OVER (partition BY answer) AS total,
       CAST(COUNT(*) OVER (partition BY answer) AS FLOAT) * 100 /
       COUNT(*) OVER () AS percentage
FROM fast_survey

Demo on SQLFiddle