select account, amount from
(
select account, amount, rank() over (partition by account order by amount desc) rankval
from mytable
)
where rankval <= 10;
You may want to use DENSE_RANK or ROW_NUMBER instead of RANK, depending on your needs. This shows the difference:
SQL> select deptno, ename, sal,
2 rank() over (partition by deptno order by sal desc) rank,
3 dense_rank() over (partition by deptno order by sal desc) dense_rank,
4 row_number() over (partition by deptno order by sal desc) row_number
5 from emp
6 /
DEPTNO ENAME SAL RANK DENSE_RANK ROW_NUMBER
---------- ---------- ---------- ---------- ---------- ----------
10 KING 5000 1 1 1
10 CLARK 2450 2 2 2
10 MILLER 1300 3 3 3
20 SCOTT 3000 1 1 1
20 FORD 3000 1 1 2
20 JONES 2975 3 2 3
20 ADAMS 1100 4 3 4
20 SMITH 800 5 4 5
30 BLAKE 2850 1 1 1
30 ALLEN 1600 2 2 2
30 TURNER 1500 3 3 3
30 WARD 1250 4 4 4
30 MARTIN 1250 4 4 5
30 JAMES 950 6 5 6
Look at deptno 20. This has 2 employees who tie for highest salary.
RANK makes them both #1 and then the next employee is #3.
DENSE_RANK makes them both #1 and then the next employee is #2.
ROW_NUMBER gives every row a unique number.