Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calculating percentages with GROUP BY query

I have a table with 3 columns which looks like this:

File    User     Rating (1-5) ------------------------------ 00001    1        3 00002    1        4 00003    2        2 00004    3        5 00005    4        3 00005    3        2 00006    2        3 Etc. 

I want to generate a query that outputs the following (for each user and rating, display the number of files as well as percentage of files):

User    Rating   Count   Percentage ----------------------------------- 1       1         3      .18 1       2         6      .35 1       3         8      .47 2       5         12     .75 2       3         4      .25 

With Postgresql, I know how to create a query that includes the first 3 columns using the following query, but I can't figure out how to calculate percentage within the GROUP BY:

SELECT     User,     Rating,     Count(*) FROM     Results GROUP BY     User, Rating ORDER BY     User, Rating 

Here I want the percentage calculation to apply to each user/rating group.

like image 446
DeadMonkey Avatar asked Jun 01 '11 20:06

DeadMonkey


People also ask

How do you find the percentage between two groups?

Multiply the value of "X" and "Y" by 100 to obtain the percent share of the total for each group. Completing the example: 0.56 times 100 equals 56 percent, which is the percentage of the people in the movie theater who are men. Similarly, 0.44 times 100 equals a share of 44 percent of people who are women at the movie.

How do you calculate percent discount in SQL query?

The formula will need to be something like: col1 * 0. col2 (both columns 1&2 can be null). Col1 is the GrossAmount(decimal(10,2) and Col2(smallint) is the percent discount.


2 Answers

WITH t1 AS   (SELECT User, Rating, Count(*) AS n    FROM your_table   GROUP BY User, Rating) SELECT User, Rating, n,         (0.0+n)/(COUNT(*) OVER (PARTITION BY User)) -- no integer divide! FROM t1; 

Or

SELECT User, Rating, Count(*) OVER w_user_rating AS n,          (0.0+Count(*) OVER w_user_rating)/(Count(*) OVER (PARTITION BY User)) AS pct FROM your_table WINDOW w_user_rating AS (PARTITION BY User, Rating); 

I would see if one of these or the other yields a better query plan with the appropriate tool for your RDBMS.

like image 99
Andrew Lazarus Avatar answered Oct 23 '22 10:10

Andrew Lazarus


Alternatively, you can do the old-school way — arguably easier to grok:

select usr.User                   as User   ,        usr.Rating                 as Rating ,        usr.N                      as N      ,        (100.0 * usr.N) / total.N as Pct from ( select User, Rating , count(*) as N        from Results        group by User , Rating      ) usr join ( select User , count(*) as N        from Results        group by User      ) total on total.User = usr.User order by usr.User, usr.Rating 

Cheers!

like image 21
Nicholas Carey Avatar answered Oct 23 '22 09:10

Nicholas Carey