This question already has answers here:
Fetch the rows which have the Max value for a column for each distinct value of another column
(35 answers)
Closed 8 years ago.
I would like to know if I have a certain table, let's say table X
which contains salary and names, how would I display the maximum salary along with corresponding names?
Thank you.
select salary, name
from X
where salary = (select MAX(salary) from X)
Let's see this using EMP table example :
SQL> WITH DATA AS(
2 SELECT MAX(sal) max_sal FROM emp)
3 SELECT ename, sal
4 FROM emp
5 WHERE sal = (SELECT max_sal FROM DATA)
6 /
ENAME SAL
---------- ----------
KING 5000
SQL>
Related
I have a table on employees like this:
ENAME JOB
Jack Clerk
Adam Manager
Raphael President
And my idea is to get the names that have the maximum length and the minimum length (1 per each) and in case the length is the same, take the one that goes first alphabetically (for example in the case of Jack and Adam, both with 4 characters, it would take Adam):
ENAME LENGTH
Adam 4
Raphael 7
I couldn't find the way of doing it in one unique query so I tried to join two queries but it keeps giving me error ('ORA-00933: SQL command not properly ended') and I don't know why:
SELECT ENAME, LENGTH(ENAME) FROM EMP
GROUP BY ENAME
HAVING LENGTH(ENAME) = (SELECT MAX(LENGTH(ENAME)) FROM emp)
ORDER BY ENAME
FETCH FIRST 1 ROW ONLY
union all
SELECT ENAME, LENGTH(ENAME) FROM EMP
GROUP BY ENAME
HAVING LENGTH(ENAME) = (SELECT MIN(LENGTH(ENAME)) FROM emp)
ORDER BY ENAME
FETCH FIRST 1 ROW ONLY;
SELECT ENAME, LENGTH(ENAME) FROM EMP
GROUP BY ENAME
HAVING LENGTH(ENAME) = (SELECT MAX(LENGTH(ENAME)) FROM emp)
--ORDER BY 1
--FETCH FIRST 1 ROW ONLY
union
SELECT ENAME, LENGTH(ENAME) FROM EMP
GROUP BY ENAME
HAVING LENGTH(ENAME) = (SELECT MIN(LENGTH(ENAME)) FROM emp)
ORDER BY 1
FETCH FIRST 1 ROW ONLY;
One method uses aggregation and union all:
select min(name) keep (dense_rank first order by len(name) asc), min(len(name))
from emp
union all
select min(name) keep (dense_rank first order by len(name) desc, max(len(name))
from emp;
The keep syntax is Oracle's rather verbose way of having a "first" aggregation function.
This question already has answers here:
Oracle - deleting duplicates
(2 answers)
How to delete duplicate records from a table in oracle
(5 answers)
Removing duplicate rows from table in Oracle
(24 answers)
Closed 2 years ago.
I hava a table emp, I wish to delete the duplicate values.
The subquery is good.
SELECT ename
FROM emp
GROUP BY ename
HAVING Count(empno) > 1
But when I do the delete operation its deleting all the lines. I don't understand what mistake I'm doing.
DELETE FROM emp
WHERE ename IN (SELECT ename
FROM emp
GROUP BY ename
HAVING Count(empno) > 1);
It deletes all ENAMEs, not only duplicates (i.e. it doesn't leave one row). Try something like
Table contents at beginning:
SQL> select * From temp order by id;
ID ENAME
---------- ----------
1 Little
2 Little --> duplicate ENAME
3 Foot
Deleting:
SQL> delete from temp a
2 where a.rowid > (select min(b.rowid)
3 from temp b
4 where b.ename = a.ename
5 );
1 row deleted.
Result;
SQL> select * From temp order by id;
ID ENAME
---------- ----------
1 Little
3 Foot
SQL>
This question already has answers here:
How to find the employee with the second highest salary?
(5 answers)
Closed 3 years ago.
I have to get the name of employee with the second highest salary the table name from where I am fetching is emp. I know the query for second highest salary which is
select max(sal)
from emp
where sal < (select max(sal) from emp)
it works and it returns the right answer.
But I have to get the name of the employee as well. I simply tried
select name, max(sal)
from emp
where sal < (select max(sal) from emp)
I get this error:
ORA-00937: not a single-group group function
how can i remove the error in order to get the name and salary both.
thank you to anyone who helps.
You can use
select name,sal from emp where sal = (select max(sal) from emp where sal < (select max(sal) from emp));
use this :
with cte (
select ROW_NUMBER() over(order by sal desc)rnum ,name,sal from emp )
select * from cte where rnum = 2
You can get this easily with a window function. Try something like this:
SELECT name, sal
FROM emp
QUALIFY RANK OVER(ORDER BY sal DESC) = 2
This will order your rows by Salary and then give each row a ranking. Then it will return the rows with ranking = 2.
If you want to ensure you only get one row back, change RANK to ROW_NUMBER.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I want to display top 3 rows of the table without where condition
This would return the first 3 rows:
SELECT * FROM TABLE1 WHERE ROWNUM <= 3;
However, the results would be non-deterministic without an ORDER BY. So use something like:
SELECT * FROM TABLE1 WHERE ROWNUM <= 3 ORDER BY COLUMN1;
Is this OK to be without where condition ..? :
select empno, deptno, ename
from
( select deptno, empno, ename,
row_number() over(order by empno desc) rn
from emp ) e join
(
select level lvl
from dual
connect by level <= 3
) l on ( l.lvl = e.rn );
EMPNO DEPTNO ENAME
----- ------ ------
7934 10 MILLER
7902 20 FORD
7900 30 JAMES
where emp is classical employee table of Oracle.
Say there's a table
Name Salary
Joe 4000
Steve 6000
I could just do this
select name from emp where salary = (select max(salary) from emp);
but is there a way to do this without using a subquery?? Please help.
EDIT: Sorry I forgot to mention that I'm using Oracle 10g and LIMIT doesn't work on it
You didn't mention the version of Oracle.
On Oracle 12 there is a new low limiting clause that can be used:
SELECT name
FROM emp
ORDER BY salary desc
FETCH FIRST 1 ROWS ONLY;
There are examples in documentation: https://docs.oracle.com/database/121/SQLRF/statements_10002.htm#BABEAACC
On earlier versions it can't be done without using a subquery, but if you must then create a view:
CREATE VIEW emp_ordered AS
SELECT *
FROM emp
ORDER BY salary desc;
and then query this view in this way:
SELECT * FROM emp_ordered
WHERE rownum <=1
ANSI SQL answer (no dbms specified):
select Name, Salary
from emp
order by Salary desc
fetch first 1 row only
Edit: Will work with newer Oracle versions.
In Oracle 12c, the top-n row limiting feature is introduced. Which allows to ORDER the rows without an additional subquery. So, no more dependency on ROWNUM and explicit sorting in a subquery.
For example,
SQL> SELECT ename, sal FROM emp ORDER BY sal DESC
2 FETCH FIRST 1 row only;
ENAME SAL
---------- ----------
KING 5000
SQL>
Update Regarding duplicate rows
There is an option WITH TIES which will include the duplicate rows.
For example,
SQL> insert into emp(empno, ename, sal) values(1234, 'LALIT', 5000);
1 row created.
SQL> SELECT ename, sal FROM emp ORDER BY sal DESC FETCH FIRST 1 ROWS WITH TIES;
ENAME SAL
---------- ----------
KING 5000
LALIT 5000
SQL>
Try this
SELECT name FROM emp
ORDER BY salary DESC
LIMIT 1
Try
select * from emp order by salary DESC limit 1