An example for the problem mentioned in my comment on the accepted answer:
select avg(Total) median from ( select Total, rnasc = row_number() over(order by Total), rndesc = row_number() over(order by Total desc) from [Table] ) b where rnasc between rndesc - 1 and rndesc + 1
This snippet is not guaranteed to work if there are duplicate values ββin the input dataset, so row_number () will not provide the expected values.
For example, to enter:
DROP TABLE #b CREATE TABLE #b (id INT IDENTITY, Total INT) INSERT INTO #b SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 5 UNION ALL SELECT 5 UNION ALL SELECT 5
The internal request is returned (I think it may differ on different servers):
Total rnasc rndesc 5 3 1 5 4 2 5 5 3 1 1 4 1 2 5
An external runnig request will result in NULL (since there is no line where rnasc is between rndesc-1 and rndesc + 1)
A simple solution is to add some surrogate key (I used the identification column) to the data set and include this column in the OVER () clause:
SELECT avg(Total) median from ( SELECT Total, rnasc = row_number() over(order by Total, id), rndesc = row_number() over(order by Total DESC, id desc) from
Now the sort order is guaranteed and an internal query is returned:
Total rnasc rndesc 5 5 1 5 4 2 5 3 3 1 2 4 1 1 5
And the result is correct :)
ulath source share