Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 4334896
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 21, 20262026-05-21T10:35:45+00:00 2026-05-21T10:35:45+00:00

I hope you can help me with my homework :) We need to build

  • 0

I hope you can help me with my homework 🙂

We need to build a query that outputs the top N best paid employees.

My version works perfectly fine.
For example the top 3:

SELECT name, salary
FROM staff
WHERE salary IN ( SELECT * 
                  FROM ( SELECT salary
                         FROM staff 
                         ORDER BY salary DESC ) 
                  WHERE ROWNUM <= 3 )
ORDER BY salary DESC
;

Note that this will output employees that are in the top 3 and have the same salary, too.

1: Mike, 4080
2: Steve, 2800
2: Susan, 2800
2: Jack, 2800
3: Chloe, 1400


But now our teacher does not allow us to use ROWNUM.
I searched far and wide and didn’t find anything useable.


My second solution thanks to Justin Caves’ hint.

First i tried this:

SELECT name, salary, ( rank() OVER ( ORDER BY salary DESC ) ) as myorder
FROM staff
WHERE myorder <= 3
;

The errormessage is: “myorder: invalid identifier”

Thanks to DCookie its now clear:

“[…] Analytics are applied AFTER
the where clause is evaluated, which
is why you get the error that myorder
is an invalid identifier.”

Wrapping a SELECT around solves this:

SELECT *
FROM ( SELECT name, salary, rank() OVER ( ORDER BY salary DESC ) as myorder FROM staff )
WHERE myorder <= 3
;

My teacher strikes again and don’t allow such exotic analytic functions.

3rd solution from @Justin Caves.

“If analytic functions are also
disallowed, the other option I could
imagine– one that you would never,
ever, ever actually write in practice,
would be something like”

SELECT name, salary
  FROM staff s1
 WHERE (SELECT COUNT(*)
          FROM staff s2
         WHERE s1.salary < s2.salary) <= 3
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-21T10:35:46+00:00Added an answer on May 21, 2026 at 10:35 am

    Since this is homework, a hint rather than an answer. You’ll want to use analytic functions. ROW_NUMBER, RANK, or DENSE_RANK can work depending on how you want to handle ties.

    If analytic functions are also disallowed, the other option I could imagine– one that you would never, ever, ever actually write in practice, would be something like

    SELECT name, salary
      FROM staff s1
     WHERE (SELECT COUNT(*)
              FROM staff s2
             WHERE s1.salary < s2.salary) <= 3
    

    With regard to performance, I wouldn’t rely on the COST number from the query plan– that’s only an estimate and it is not generally possible to compare the cost between plans for different SQL statements. You’re much better off looking at something like the number of consistent gets the query actually does and considering how the query performance will scale as the number of rows in the table increases. The third option is going to be radically less efficient than the other two simply because it needs to scan the STAFF table twice.

    I don’t have your STAFF table, so I’ll use the EMP table from the SCOTT schema

    The analytic function solution actually does 7 consistent gets as does the ROWNUM solution

    Wrote file afiedt.buf
    
      1  select ename, sal
      2    from( select ename,
      3                 sal,
      4                 rank() over (order by sal) rnk
      5            from emp )
      6*  where rnk <= 3
    SQL> /
    
    ENAME             SAL
    ---------- ----------
    smith             800
    SM0               950
    ADAMS            1110
    
    
    Execution Plan
    ----------------------------------------------------------
    Plan hash value: 3291446077
    
    --------------------------------------------------------------------------------
    -
    | Id  | Operation                | Name | Rows  | Bytes | Cost (%CPU)| Time
    |
    --------------------------------------------------------------------------------
    -
    |   0 | SELECT STATEMENT         |      |    14 |   672 |     4  (25)| 00:00:01
    |*  1 |  VIEW                    |      |    14 |   672 |     4  (25)| 00:00:01
    |*  2 |   WINDOW SORT PUSHED RANK|      |    14 |   140 |     4  (25)| 00:00:01
    |   3 |    TABLE ACCESS FULL     | EMP  |    14 |   140 |     3   (0)| 00:00:01
    --------------------------------------------------------------------------------
    -
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       1 - filter("RNK"<=3)
       2 - filter(RANK() OVER ( ORDER BY "SAL")<=3)
    
    
    Statistics
    ----------------------------------------------------------
              0  recursive calls
              0  db block gets
              7  consistent gets
              0  physical reads
              0  redo size
            668  bytes sent via SQL*Net to client
            524  bytes received via SQL*Net from client
              2  SQL*Net roundtrips to/from client
              1  sorts (memory)
              0  sorts (disk)
              3  rows processed
    
    SQL> select ename, sal
      2    from( select ename, sal
      3            from emp
      4           order by sal )
      5   where rownum <= 3;
    
    ENAME             SAL
    ---------- ----------
    smith             800
    SM0               950
    ADAMS            1110
    
    
    Execution Plan
    ----------------------------------------------------------
    Plan hash value: 1744961472
    
    --------------------------------------------------------------------------------
    | Id  | Operation               | Name | Rows  | Bytes | Cost (%CPU)| Time     |
    --------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT        |      |     3 |   105 |     4  (25)| 00:00:01 |
    |*  1 |  COUNT STOPKEY          |      |       |       |            |          |
    |   2 |   VIEW                  |      |    14 |   490 |     4  (25)| 00:00:01 |
    |*  3 |    SORT ORDER BY STOPKEY|      |    14 |   140 |     4  (25)| 00:00:01 |
    |   4 |     TABLE ACCESS FULL   | EMP  |    14 |   140 |     3   (0)| 00:00:01 |
    --------------------------------------------------------------------------------
    
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       1 - filter(ROWNUM<=3)
       3 - filter(ROWNUM<=3)
    
    
    Statistics
    ----------------------------------------------------------
              1  recursive calls
              0  db block gets
              7  consistent gets
              0  physical reads
              0  redo size
            668  bytes sent via SQL*Net to client
            524  bytes received via SQL*Net from client
              2  SQL*Net roundtrips to/from client
              1  sorts (memory)
              0  sorts (disk)
              3  rows processed
    

    The COUNT(*) solution, however, actually does 99 consistent gets and has to do a full scan of the table twice so it is more than 10 times less efficient. And it will scale much worse as the number of rows in the table increases

    SQL> select ename, sal
      2    from emp e1
      3   where (select count(*) from emp e2 where e1.sal < e2.sal) <= 3;
    
    ENAME             SAL
    ---------- ----------
    JONES            2975
    SCOTT            3000
    KING             5000
    FORD             3000
    FOO
    
    
    Execution Plan
    ----------------------------------------------------------
    Plan hash value: 2649664444
    
    ----------------------------------------------------------------------------
    | Id  | Operation           | Name | Rows  | Bytes | Cost (%CPU)| Time     |
    ----------------------------------------------------------------------------
    |   0 | SELECT STATEMENT    |      |    14 |   140 |    24   (0)| 00:00:01 |
    |*  1 |  FILTER             |      |       |       |            |          |
    |   2 |   TABLE ACCESS FULL | EMP  |    14 |   140 |     3   (0)| 00:00:01 |
    |   3 |   SORT AGGREGATE    |      |     1 |     4 |            |          |
    |*  4 |    TABLE ACCESS FULL| EMP  |     1 |     4 |     3   (0)| 00:00:01 |
    ----------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       1 - filter( (SELECT COUNT(*) FROM "EMP" "E2" WHERE
                  "E2"."SAL">:B1)<=3)
       4 - filter("E2"."SAL">:B1)
    
    
    Statistics
    ----------------------------------------------------------
              0  recursive calls
              0  db block gets
             99  consistent gets
              0  physical reads
              0  redo size
            691  bytes sent via SQL*Net to client
            524  bytes received via SQL*Net from client
              2  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
              5  rows processed
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I hope you can help me. I have a web service that needs to
I have a small problem, but I hope somebody can help. Let's say that
hope someone can help. I appreciate there are a few questions that are similar
Hope you can help. I'm looking for a way to build an excel sheet
Hope you can help me with this one. I need to make a program
hope you can help me coding. What i need to do: 1.) I should
hope you can help, this is driving me up the wall I need to
Needing help for some homework. I hope someone can help me out as I
hope you can help me, again :) i want to build a little webbased
Hope you can help me with the following: I need to add an action

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.