没有包含百分号(% 字符)的 numeric type,因此您的问题不能仅通过计算数值的表达式来解决。除了计算那个值,你还需要format it as text using the to_char() function。
此函数接受一个数值并使用您作为第二个参数提供的格式文字将其转换为文本值。在这种情况下,看起来您想要做的是四舍五入到最接近的百分比并显示百分号。您可能希望使用 '990%' 作为格式化文字。将此添加到您的示例表和the window function that Gordon suggested 产量:
[local] air@postgres=> CREATE TABLE movies AS SELECT * FROM ( VALUES
... ('Robert DeSouza'),
... ('Tony Wagner'),
... ('Sean Cortese'),
... ('Robert DeSouza'),
... ('Robert DeSouza'),
... ('Tony Wagner'),
... ('Sean Cortese'),
... ('Charles Bastian'),
... ('Robert DeSouza')
... ) AS t(actors);
SELECT 9
Time: 715.613 ms
[local] air@postgres=> select actors, to_char(100 * count(*) / sum(count(*)) over (), '990%') as "The Ratio" from movies group by actors;
┌─────────────────┬───────────┐
│ actors │ The Ratio │
├─────────────────┼───────────┤
│ Charles Bastian │ 11% │
│ Tony Wagner │ 22% │
│ Sean Cortese │ 22% │
│ Robert DeSouza │ 44% │
└─────────────────┴───────────┘
(4 rows)
Time: 31.501 ms
您要确保考虑到显示所有可能值的需要,包括 100% 和 0%;由于to_char() 将四舍五入以适合您所需的精度,因此演员可以将其比率显示为零,尽管表中存在:
[local] air@postgres=> delete from movies where actors <> 'Tony Wagner';
DELETE 7
Time: 36.697 ms
[local] ahuth@postgres=> insert into movies (actors) select 'Not Tony Wagner' from generate_series(1,500);
INSERT 0 500
Time: 149.022 ms
[local] ahuth@postgres=> select actors, to_char(100 * count(*) / sum(count(*)) over (), '990%') as "The Ratio" from movies group by actors;
┌─────────────────┬───────────┐
│ actors │ The Ratio │
├─────────────────┼───────────┤
│ Tony Wagner │ 0% │
│ Not Tony Wagner │ 100% │
└─────────────────┴───────────┘
(2 rows)
Time: 0.776 ms
如果你想扩展它以显示小数位,只需修改格式字符串。当您想强制使用前导零或尾随零时,请在格式文字中使用 0。