简体   繁体   中英

SQL select rows without duplicates

Practicing some SQL, we have to get the name of the employees whose salary is the greatest of his department. But if in any department there were more than one employer with the greatest salary, we would not have to consider that department.

We got the first part but not the second one (because there are two employees with the same greatest salary (3,000) in the same department (20)).

This is what we did:

SQL> SELECT ename, sal, deptno FROM emp a 
     WHERE sal >= ALL (SELECT sal FROM emp WHERE deptno=a.deptno)
     ORDER BY sal;

And this is what we got:

ENAME          SAL DEPTNO
---------- ------- ------
BLAKE        2,850     30
FORD         3,000     20
SCOTT        3,000     20
KING         5,000     10

4 filas seleccionadas.

Any help will be useful, thank you!

with cte as 
(   SELECT ename, sal, deptno
         , row_number() over (partition by deptno order by sal desc) as rn 
      FROM emp 
)
select ename, sal, deptno from cte where rn = 1 
except 
select ename, sal, deptno from cte where rn = 2 
order by sal

if this does not work in oracle - it used to be also tagged mssql

You can have what you need with some analytic functions :

select ename,
       deptno,
       sal
from (
      select ename,
             deptno,
             sal,
             row_number() over(partition by deptno order by sal desc) AS num,
             count(1) over(partition by deptno, sal) AS count
      from emp
     )
where num = 1
  and count = 1

The inner query orders by salary and counts the number of employees with the same salary in the same department; the outer one simply filters for employees with the maximum salary, where only one employee has that salary in the department.

With a different approach, simply modifying your query, you can try:

SELECT ename, sal, deptno FROM emp a 
     WHERE sal >=  ALL (SELECT sal  FROM emp WHERE deptno=a.deptno)
       and (select count(1) from emp b where a.deptno = b.deptno and a.sal = b.sal) = 1

The first way gives better performance, with a single table scan, while the second one needs a nested query, thus being less efficient

SELECT ename, sal, deptno 
FROM emp a 
WHERE not exists (
  SELECT * 
  FROM emp 
  WHERE deptno=a.deptno 
    and sal >= a.sal 
    and ename != a.ename)
ORDER BY sal;

尝试使用GROUP BY column_name`,它将显示没有重复的记录。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM