-1

I have tried checking all the duplicate answers provided in this site but couldn't able to come up with rectifying my error could you guys help me out on this?

Getting this error

ORA-00923: FROM keyword not found where expected

SELECT TOP 1 sal FROM emp WHERE sal in
(SELECT DISTINCT TOP 3 sal FROM emp ORDER BY sal DESC)
ORDER BY sal ASC;

I am solving this using oracle apex site

Yogesh Sharma
  • 49,870
  • 5
  • 26
  • 52
Johny_Bravo
  • 159
  • 1
  • 2
  • 12

3 Answers3

2

You appear to want to find thew record with the third-lowest salary.

You can use a subquery to assign an analytic rank to each salary, and then filter on that:

select * from (
  select e.*, dense_rank() over (order by sal desc) as rnk
  from emp e
)
where rnk = 3;

From 12c you can use the offset and fetch syntax to do the same thing:

select * from emp
order by sal desc
offset 3 rows
fetch first row only;

You need to decide how to deal with ties though - if more than one employee shares that third-lowest salary; or even if the lowest and second lowest are awarded to more than one person. Depending on what you want to happen you can look at variations of the 12c row-limiting syntax, and other analytic functions - row_number(), dense_rank() - and their windowing options.

Alex Poole
  • 183,384
  • 11
  • 179
  • 318
  • can it be done using analytical functions lead and lag? – Johny_Bravo Dec 28 '17 at 10:12
  • Only by making it more complicated. I guess you could use lead/lag in a subquery with an offset of 3, and then filter on that being not null, and then find the first row from that subset. But why make it more difficult? – Alex Poole Dec 28 '17 at 10:23
1

I was able to get my query now

SELECT A.* FROM emp A where 3 =(SELECT COUNT(DISTINCT sal) FROM emp B WHERE A.sal <= B.sal);
Johny_Bravo
  • 159
  • 1
  • 2
  • 12
1

Yet another option, using analytic function:

WITH ranks
     AS (SELECT empno, DENSE_RANK () OVER (ORDER BY sal DESC) rnk FROM emp)
SELECT e.*
  FROM emp e, ranks r
 WHERE e.empno = r.empno 
   AND r.rnk = 3;
Littlefoot
  • 131,892
  • 15
  • 35
  • 57