Thanks! It works for the first 20 rows, however it doesn't for the next 20 rows.

/* doesn't work for next 20 rows*/

SELECT A.STUDENT_ID , TO_CHAR(A.REGISTER_DATE, 'DD-MM-YYYY HH24:MI') AS REG_DATE, NEWS_ROW
FROM
( SELECT ST.STUDENT_ID ,
ST.REGISTER_DATE , ROWNUM AS NEWS_ROW
FROM STUDENT ST, SUBJECT SB
WHERE ST.SUDENT_ID = SB.STUDENT_ID AND
SB.SUBJECT_NAME LIKE '%MATH%' AND
ST.REGISTER_DATE >= TO_DATE('01-10-2000', 'DD-MM-YYYY')
ST.REGISTER_DATE < TO_DATE('01-11-2000', 'DD-MM-YYYY') + 1
ORDER BY REG_DATE DESC ) A ,
STUDENT ST
WHERE ST.STUDENT_ID = A.STUDENT_ID AND
NEWS_ROW >= 20 and
NEWS_ROW <= 40
/

/* this works for next 20 rows, why? */

SELECT B.* FROM
( SELECT A.STUDENT_ID , TO_CHAR(A.REGISTER_DATE, 'DD-MM-YYYY HH24:MI') AS REG_DATE, NEWS_ROW
FROM
( SELECT ST.STUDENT_ID ,
ST.REGISTER_DATE , ROWNUM AS NEWS_ROW
FROM STUDENT ST, SUBJECT SB
WHERE ST.SUDENT_ID = SB.STUDENT_ID AND
SB.SUBJECT_NAME LIKE '%MATH%' AND
ST.REGISTER_DATE >= TO_DATE('01-10-2000', 'DD-MM-YYYY')
ST.REGISTER_DATE < TO_DATE('01-11-2000', 'DD-MM-YYYY') + 1
ORDER BY REG_DATE DESC ) A ,
STUDENT ST
WHERE ST.STUDENT_ID = A.STUDENT_ID ) B
WHERE NEWS_ROW >= 20 and
NEWS_ROW <= 40

By the way, will there be any performance issue for the sql as there is a lot of sorting involved? Thanks! :)