查找相对百分比
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
假设 answer
是 boolean
。否则,适应。
聚合 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
如果您希望百分比更精确(对于上述查询,它是一个整数除法),请将第一个 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
我有一个用户投票的民意调查。例如:
你想要菲亚特吗?
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
假设 answer
是 boolean
。否则,适应。
聚合 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
如果您希望百分比更精确(对于上述查询,它是一个整数除法),请将第一个 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