What's the best way to calculate percentile rankings (e.g. the 90th percentile or the median score) in MSSQL 2005?
I'd like to be able to select the 25th, median, and 75th percentiles for a single column of scores (preferably in a single record so I can combine with average, max, and min). So for example, table output of the results might be:
Group MinScore MaxScore AvgScore pct25 median pct75 ----- -------- -------- -------- ----- ------ ----- T1 52 96 74 68 76 84 T2 48 98 74 68 75 85
The PERCENT_RANK() function returns a percentile ranking number which ranges from zero to one. In this formula, rank is the rank of the row. total_rows is the number of rows that are being evaluated. Based on this formula, the PERCENT_RANK() function always returns zero for the first row the result set.
Ntile is where the data is divided into that "tile" where we can think of the tile having a size, and all those sizes being the same for each tile. For your 95th percentile, you want the place where the data is divided for the 95th time. That would be the START of the 95th percentile or the MIN, not the MAX.
For example, PERCENTILE_DISC (0.5) will compute the 50th percentile (that is, the median) of an expression. PERCENTILE_DISC calculates the percentile based on a discrete distribution of the column values. The result is equal to a specific column value.
I would think that this would be the simplest solution:
SELECT TOP N PERCENT FROM TheTable ORDER BY TheScore DESC
Where N = (100 - desired percentile). So if you wanted all rows in the 90th percentile, you'd select the top 10%.
I'm not sure what you mean by "preferably in a single record". Do you mean calculate which percentile a given score for a single record would fall into? e.g. do you want to be able to make statements like "your score is 83, which puts you in the 91st percentile." ?
EDIT: OK, I thought some more about your question and came up with this interpretation. Are you asking how to calculate the cutoff score for a particular percentile? e.g. something like this: to be in the 90th percentile you must have a score greater than 78.
If so, this query works. I dislike sub-queries though, so depending on what it was for, I'd probably try to find a more elegant solution. It does, however, return a single record with a single score.
-- Find the minimum score for all scores in the 90th percentile SELECT Min(subq.TheScore) FROM (SELECT TOP 10 PERCENT TheScore FROM TheTable ORDER BY TheScore DESC) AS subq
Check out the NTILE command -- it will give you percentiles pretty easily!
SELECT SalesOrderID, OrderQty, RowNum = Row_Number() OVER(Order By OrderQty), Rnk = RANK() OVER(ORDER BY OrderQty), DenseRnk = DENSE_RANK() OVER(ORDER BY OrderQty), NTile4 = NTILE(4) OVER(ORDER BY OrderQty) FROM Sales.SalesOrderDetail WHERE SalesOrderID IN (43689, 63181)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With