问题
I've made an SQL query which rank pages by how many times they have been viewed. For instance,
╔══════╦═══════╗
║ PAGE ║ VIEWS ║
╠══════╬═══════╣
║ J ║ 100 ║
║ Q ║ 77 ║
║ 3 ║ 55 ║
║ A ║ 23 ║
║ 2 ║ 6 ║
╚══════╩═══════╝
Now what I would like to do is find the percentile rank of each page using an SQL query. The math I would like to use for this is simple enough, I just want to take the row number of the already generated table divided by the total number of rows. Or 1 minus this value, depending on my interests.
Can I do a COUNT(pages) on an already generated table like this? I realize that's how I will get the total number of rows. But are there any commands to return a row number?
Just to further clarify my question I need the following results
╔══════╦════════════════╗
║ PAGE ║ Percentile ║
╠══════╬════════════════╣
║ J ║ (1-1/5)*100 ║
║ Q ║ (1-2/5)*100 ║
║ 3 ║ (1-3/5)*100 ║
║ A ║ (1-4/5)*100 ║
║ 2 ║ (1-5/5)*100 ║
╚══════╩════════════════╝
Or in general (1-(row number)/(COUNT(page))*100
回答1:
SELECT page,
views,
(1-ranks/totals)*100 Percentile
FROM
(
SELECT page,
views,
@rank:=@rank + 1 ranks,
(SELECT COUNT(*) FROM tableName) totals
FROM tableName a,
(SELECT @rank:=0) s
ORDER BY views DESC
) s
- SQLFiddle Demo
回答2:
You cannot calculate percentile ranks across a table in a single SQL statement. The approach suggested by John Woo here falls apart after the top ranks are calculated, even though the results do look good for the first (unpredictable) percent of the table being processed, meaning the top few percentiles.
The reason why is explained in this post by Oracle Ace Roland Bouman: http://rpbouman.blogspot.com/2009/09/mysql-another-ranking-trick.html
In short: user-defined variables are not designed to be reliable within a single SQL statement, only across multiple SQL statements.
Read the first sentence of the MySQL manual about User-Defined Variables: http://dev.mysql.com/doc/refman/5.5/en/user-variables.html "You can store a value in a user-defined variable in one statement and then refer to it later in another statement."
Then in about the 10th paragraph see this clear statement: "As a general rule, other than in SET statements, you should never assign a value to a user variable and read the value within the same statement. [. . .] the order of evaluation for expressions involving user variables is undefined. "
来源:https://stackoverflow.com/questions/15241247/sql-rank-percentile