There is no numeric type that includes a percent sign (the %
character) so your problem can't be solved solely by an expression that calculates the numeric value. In addition to calculating that value, you need to format it as text using the to_char()
function.
This function takes a numeric value and converts it to a text value using a formatting literal that you provide as the second argument. In this case it looks like what you want to do is to round to the nearest percent and show the percent sign. You probably want to use '990%'
as your formatting literal. Adding this to your example table and the window function that Gordon suggested yields:
[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
You want to make sure you account for the need to display a full range of possible values, including 100% and 0%; since to_char()
will round to fit your desired precision, it is possible for an actor to show zero as their ratio, despite existing in the table:
[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
If you want to expand this to show decimal places, just modify the format string. Use 0
in your formatting literal when you want to force leading or trailing zeros.