Well, one has to be fair and explain that the kmesser's sollution is more an exception then a general sollution. If instead of EMPNO you put SAL column yo won't get the 5 employees with highest sallaries! The more general solution for top-N queries would be:
select * from (select * from emp order by sal desc) where rownum < 6;
This will return 5 top paid employees. It is also worth noting that the above query will work only in 8i, because you can't use ORDER BY inside a view prior to 8i. Kmesser's query will work also with earlier releases, but the results will be wrong with pre-8i databases, because the optimizer's operation STOPKEY, which causes the results to be correct, was introduced in 8i.
Jurij Modic ASCII a stupid question, get a stupid ANSI
24 hours in a day .... 24 beer in a case .... coincidence?
the query worked for empno because it is ur primary key column and has index on it. while rows are fetched by primary key column it will be fetched in ordered manner. so the query worked.
for sal column first rows are fetched as in the database and only first 5 rows are fetched using primary key and with the result set it will order so u are not able to get the right answer.
so order by works after rows are fetched from the database.
In Orcle7 the top-N and bottom-N queries are much more complicated (particularry the top-N, where you have to sort records in descending order) and much less efficient.
If we stick with the "top 5 paid employees" example from SCOTT.EMP, here are three different queries that will return correct results. The first one is the most "straightforward", but also by far the most inefficient for large tables. The last one is the fastest one, particulary if there is an index on the sorting column. Note also that if there are equal values at the end of the result set (e.g. if there are more then one employee with the same salary at the fifth position) the first query will return none of them, while other two will return only one of them.
1. With corelated subquery
SELECT * FROM scott.emp e1 WHERE 5 >=
(SELECT COUNT(sal)
FROM scott.emp e2
WHERE e2.sal >= e1.sal)
ORDER BY e1.sal DESC;
2. With inline view
SELECT emp.* FROM emp,
(SELECT rowid x, -1*sal FROM emp GROUP BY -1*sal, rowid) e2
WHERE emp.rowid = e2.x AND rownum <= 5
ORDER BY emp.sal DESC;
3. With "dummy" outer join
SELECT emp.* FROM emp, dual
WHERE -1*emp.sal = DECODE(dual.dummy(+), 'X', NULL, NULL)
AND rownum <= 10
ORDER BY emp.sal DESC;
HTH,
Jurij Modic ASCII a stupid question, get a stupid ANSI
24 hours in a day .... 24 beer in a case .... coincidence?
Bookmarks