it works - badly - by looking at the ctc value fro each row and comparing it with the number of values which are greater than it. So what it does for each row is examine the entire table in the inner select and compare each value...nasty, slow and somewhat stupid.
A better solution would be to order the data by salary and then just get the fifth item:
WITH myTableWithRows AS (
SELECT (ROW_NUMBER() OVER (ORDER BY emp.ctc)) as row,*
SELECT * FROM myTableWithRows WHERE row = 5
You may want to add a GROUP BY clause in there to restrict the salaries just just the distinct values.