I have a table emp (ename,eid,did,sal,sex) where column did is foreign key with another table dept (did,dname).
I want to get the max sal of the company along with name and did of the person who is getting it.
I am executing following query
select did,ename ,max(sal) from emp;
But the Result is :
ORA-00937: not a single-group group function
so My question is can't I have more than 1 columns ?
You can't use MAX aggregate function like this. Using MAX without a GROUP BY clause will just return one record with the maximum sal value. You are not allowed to place any more non-aggregated fields in the SELECT clause.
If you want to get the record having the maximum sal value, then you have to do a self-join:
select e1.*
from emp as e1
inner join (
select max(sal) as max_sal
from emp
) as e2 on e1.sal = e2.max_sal
Note: The above query will return more than one records from table emp, in case more than one records share the same maximum sal value.
Edit:
If you want to get the maximum salary per department then you have to include a GROUP BY clause in the derived table used:
select e1.*
from emp as e1
inner join (
select did, max(sal) as max_sal
from emp
group by did
) as e2 on e1.did = e2.did and e1.sal = e2.max_sal
You would have to group the results by the sal column:
select did,ename,max(sal) from emp group by sal
MAX operates over the group specified in a GROUP BY clause and finds the maximum value for each group. When not specifying a set of columns to group by, it finds the max for the entire results set.
You need to find the max sal, then you can query the rows that match:
select did, ename, sal
from emp
where sal = (select max(sal) from emp)
Related
I'm trying to group some max values by an ID (until here i got it figured out), and I also need to select the names from the persons with the max values, so my grouping should allow duplicates if two persons with that grouped ID have the same value (max).
Here's what I've got so far.
SELECT MGR,MAX(SAL) AS MaxSal
FROM EMP
WHERE MGR IS NOT NULL
GROUP BY MGR
Now I also need to extract the field ENAME, how could I do this, while grouping and also allowing duplicate groups when necessary ?
Starting Oracle 12c, one option uses window functions in the order by clause and a fetch clause:
select mgr, ename, sal
from emp
where mgr is not null
order by rank() over(partition by mgr order by sal desc)
fetch first row with ties
The solution is analytic functions. Here's how I achieved my desired result.
SELECT MGR,ENAME,SAL
FROM
(
SELECT MGR,ENAME,SAL,
MAX(SAL) OVER (PARTITION BY MGR) AS MaxSal
FROM EMP
)
WHERE SAL=MaxSal
Return the department number and the total payroll for the department that has the highest payroll. Payroll is the sum of all salaries and commissions of the department. Use a having clause with a nested table expression.
select e0.deptno,
(select sum(sal+com) FROM emp
group by deptno
having sum(sal+com) >= all(select sum(sal+com)
from emp
group by deptno) )as top
from emp as e0
group by e0.deptno
;
But my result is not correct. Im not so sure if my nested table expression combined with the having clause is done the right way. Can someone, try to help me? Thanks in advance.
As far as concerned, you don't need a having clause for this. You can just aggregate by department, order the results by payroll and fetch the first record:
select deptno, sum(sal + com) payroll
from emp e
group by deptno
order by payroll desc
fetch first 1 rows only
If you do want to use having (or if you are using a version of db2 that does not support the fetch ... rows ... clause), then we can build on your initial idea as follows:
select deptno, sum(sal + com) payroll
from emp
group by deptno
having sum(sal + com) >= all (
select sum(sal + com) from emp group by deptno
)
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.
I want to Display department number, names and salaries of employees who are earning max salary in their departments which are in the same table.
I am using oracle sql. The Table structure I am using is
Emp(Empno,Ename,Job,Salary,Deptno)
I have read about this and I think that this can be done by the use of correlated sub-queries. The query I fired was
select E1.Ename,E1.Ename,E1.Salary
from Emp E1
where E1.Empno=(
select Empno
from Emp E2
where Salary=(
select max(Salary)
from Emp
where Deptno=E1.Deptno
)
);
This gives an error saying "single-row subquery returns more than one row".
What am I doing wrong? What should do to correct it?
SELECT EmpNo, Ename,Job,Salary,Deptno
FROM
(
SELECT EmpNo, Ename,Job,Salary,Deptno,
DENSE_RANK() OVER (PARTITION BY DeptNo
ORDER BY Salary DESC ) rn
FROM Emp
) a
WHERE a.rn = 1
DENSE_RANK
or by using MAX
SELECT a.*
FROM Emp a
INNER JOIN
(
SELECT DeptNo, MAX(Salary) Max_sal
FROM Emp
GROUP BY DeptNo
) b ON a.DeptNo = b.DeptNo AND
a.Salary = b.Max_SAL
I want to display the name of department with highest SUM of salary.
I am using oracle sql and the table structure is Dept(Deptno,Dname,Loc) and Emp(Empno,Ename,Job,Salary,Deptno).
The query I use was
select Dname
from Dept
where Deptno=
( select Deptno
from Emp
where rownum=1
group by Deptno
order by sum(Salary) Desc
);
This gives an error:
Right parenthesis missing.
When I run the sub-query alone, it successfully returns a Deptno. But with the parent query, I get the above error.
What is the problem and what can be the possible solution?
select dname
from (select dname, rank() over (order by sum(salary) desc) rnk
from dept d
inner join emp e
on e.deptno = d.deptno
group by dname, e.deptno
)
where rnk = 1;
note, in your example putting where rownum=1 where you did is a huge bug. it would mean pick 1 random row and sort it (not really the highest salary row..just any old row)
my solution may get over 1 row if 2 deptartments have the same highest salary. you can use row_number() instead of rank() to just pick one if you want.