簡體   English   中英

如何編寫 SQL 查詢以在 Oracle 中查找最高和最低工資以及員工姓名

[英]How to write SQL query to find max and min salary along with employee name in Oracle

我有一張員工表。 請在下面找到表結構和數據。

在此處輸入圖像描述

我想找到最高工資和最低工資以及員工姓名。

預計 output 將是:

在此處輸入圖像描述

為了找出最高薪水和員工姓名,我寫了這個查詢:

SELECT name,salary FROM  employee where salary
= (select max(salary) from employee);

為了找出最低工資和員工姓名,我寫了這個查詢:

SELECT name,salary FROM  employee where salary
= (select min(salary) from employee);

但我無法合並這兩個查詢。

有人可以指導我構建 SQL 查詢,該查詢將返回最高薪水和最低薪水以及員工姓名嗎?

這是一種使用RANK 這個答案在CTE中進行一次通過,以找到員工表中排名最低和排名最高的工資。 然后,它只查詢一次子查詢以檢索完整的匹配記錄。

WITH cte AS (
    SELECT NAME, SALARY,
        RANK() OVER (ORDER BY SALARY) rnk_min,
        RANK() OVER (ORDER BY SALARY DESC) rnk_max
    FROM employee
)

SELECT NAME, SALARY
FROM cte
WHERE rnk_min = 1 OR rnk_max = 1
ORDER BY SALARY;

在此輸入圖像描述

演示

如果您希望將它們全部返回到單個記錄中,請執行以下操作:

WITH t1 AS (
    SELECT name, salary FROM  employee where salary
    = (select max(salary) from employee) ),
t2 AS (    
    SELECT name, salary FROM  employee where salary
    = (select min(salary) from employee) )
SELECT
    t1.name AS MAX_NAME, t1.salaray AS MAX_SALARY, t2.name AS MIN_NAME, t2.salaray AS MIN_SALARY
FROM t1 LEFT JOIN t2 ON 1=1

這會將您的查詢放入公用表表達式(CTE,基本上就像您可以查詢的自己的表一樣)。 然后,它將它們連接在任意真的1 = 1上。 然后你只需選擇四個值。

你可以使用union all or

SELECT e.name, e.salary
FROM employee e
WHERE e.salary = (SELECT MAX(e2.salary) FROM employee e2) OR
      e.salary = (SELECT MIN(e2.salary) FROM employee e2);

您還可以使用self-join alike查詢邏輯

with Employee(name, salary) as
(
 select 'Rick',3000 from dual union all
 select 'John',4000 from dual union all
 select 'Shane',3000 from dual union all
 select 'Peter',5000 from dual union all
 select 'Jackob',7000 from dual
)
 select name, salary
   from Employee
   join ( select max(salary) as max_sal, 
                 min(salary) as min_sal
           from Employee )
      on  salary in ( min_sal, max_sal )
  group by name, salary
  order by salary desc, name;

 NAME   SALARY
 ------ -------
 Jackob  7000
 Rick    3000
 Shane   3000

dbfiddle.uk演示

如果您按照自己的意思編寫代碼 ,則可以獲得所有員工的工資[ IN ]最低(工資)或最高工資(工資)

SELECT e.name, e.salary
FROM employee e
WHERE e.salary in ( 
  select min(salary) sal from employee 
    union 
  select max(salary) from employee);

重要的是定義薪水指數

 create index  employee_Idx on  employee(salary);

查詢進行兩次索引訪問以獲取最小值和最大值 - 下面的計划中的第7行和第9行。 與使用此選定值相比, NESTED LOOPS執行對salary索引訪問和ROWID的表訪問。

請注意,此優化表明只有少數行具有極高的工資(這通常是這種情況 - 至少對於MAX ;)

| Id  | Operation                       | Name         | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                |              |     3 |    66 |     6  (34)| 00:00:01 |
|   1 |  NESTED LOOPS                   |              |     3 |    66 |     6  (34)| 00:00:01 |
|   2 |   NESTED LOOPS                  |              |     3 |    66 |     6  (34)| 00:00:01 |
|   3 |    VIEW                         | VW_NSO_1     |     2 |    26 |     4  (50)| 00:00:01 |
|   4 |     SORT UNIQUE                 |              |     2 |     6 |     4  (50)| 00:00:01 |
|   5 |      UNION-ALL                  |              |       |       |            |          |
|   6 |       SORT AGGREGATE            |              |     1 |     3 |     2  (50)| 00:00:01 |
|   7 |        INDEX FULL SCAN (MIN/MAX)| EMPLOYEE_IDX |     1 |     3 |     1   (0)| 00:00:01 |
|   8 |       SORT AGGREGATE            |              |     1 |     3 |     2  (50)| 00:00:01 |
|   9 |        INDEX FULL SCAN (MIN/MAX)| EMPLOYEE_IDX |     1 |     3 |     1   (0)| 00:00:01 |
|* 10 |    INDEX RANGE SCAN             | EMPLOYEE_IDX |     1 |       |     0   (0)| 00:00:01 |
|  11 |   TABLE ACCESS BY INDEX ROWID   | EMPLOYEE     |     1 |     9 |     1   (0)| 00:00:01 |
------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

  10 - access("E"."SALARY"="SAL")

用postgresql試過

select sub.emp_name, sub.salary 
from (
select *, 
dense_rank() over (order by salary) as my_rank,
dense_rank() over (order by salary desc) as my_rank_desc
from employee ) sub
where my_rank = 1 or my_rank_desc = 1
order by salary 
select first_name,last_name, role,salary from emp_record_table  
where salary in(
select max(salary) from emp_record_table group by role 
union  
select min(salary) from emp_record_table group by role  ) ; 

開/關

Arthur  Black   PRESIDENT   16500
Eric    Hoffman LEAD DATA SCIENTIST 8500
William Butler  LEAD DATA SCIENTIST 9000
Dianna  Wilson  SENIOR DATA SCIENTIST   5500
Dorothy Wilson  SENIOR DATA SCIENTIST   7700
Steve   Hoffman ASSOCIATE DATA SCIENTIST    5000
Pete    Allen   MANAGER 11000
David   Smith   ASSOCIATE DATA SCIENTIST    4000
Chad    Wilson  ASSOCIATE DATA SCIENTIST    5000
Tracy   Norris  MANAGER 8500
Katrina Allen   JUNIOR DATA SCIENTIST   3000
Jenifer Jhones  JUNIOR DATA SCIENTIST   2800

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM