[英]How to write SQL query to find max and min salary along with employee name in Oracle
I have one employee table.我有一张员工表。 Please find below the table structure along with data.请在下面找到表结构和数据。
I want to find the maximum salary and minimum salary along with employee name.我想找到最高工资和最低工资以及员工姓名。
expected output will be:预计 output 将是:
To find out the maximum salary along with employee name I have written this query:为了找出最高薪水和员工姓名,我写了这个查询:
SELECT name,salary FROM employee where salary
= (select max(salary) from employee);
And to find out the minimum salary along with employee name I have written this query:为了找出最低工资和员工姓名,我写了这个查询:
SELECT name,salary FROM employee where salary
= (select min(salary) from employee);
But I am unable to merge these two queries.但我无法合并这两个查询。
Can someone please guide me to build the SQL query which will return maximum salary and minimum salary along with employee name?有人可以指导我构建 SQL 查询,该查询将返回最高薪水和最低薪水以及员工姓名吗?
Here is one way, using RANK
. 这是一种使用RANK
。 This answer makes one pass in a CTE to find the lowest and highest ranked salaries in the employee table. 这个答案在CTE中进行一次通过,以找到员工表中排名最低和排名最高的工资。 Then, it subqueries only once to retrieve the full matching records. 然后,它只查询一次子查询以检索完整的匹配记录。
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;
If you want it all returned in a single record, do this: 如果您希望将它们全部返回到单个记录中,请执行以下操作:
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
This puts both your queries into Common Table Expressions (CTEs, essentially act like their own tables you can query against). 这会将您的查询放入公用表表达式(CTE,基本上就像您可以查询的自己的表一样)。 Then, it joins them on the arbitrarily true 1=1. 然后,它将它们连接在任意真的1 = 1上。 Then you just select your four values. 然后你只需选择四个值。
You could use union all
or or
: 你可以使用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);
You can also use self-join alike
query logic 您还可以使用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
If you code as you speak you get for get all employees with salary [ IN
] min(salary) or max(salary) : 如果您按照自己的意思编写代码 ,则可以获得所有员工的工资[ 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);
The important thing is to define the index on salary 重要的是定义薪水指数
create index employee_Idx on employee(salary);
The query makes two index access to get the min and max values - lines 7 and 9 in the plan below. 查询进行两次索引访问以获取最小值和最大值 - 下面的计划中的第7行和第9行。 Than using this selected values a NESTED LOOPS
is performed with index access on salary
and a table access by ROWID. 与使用此选定值相比, NESTED LOOPS
执行对salary
索引访问和ROWID的表访问。
Note that this optimization pressumes that there are only few rows with the extreme salaries (which is normaly the case - at least for the MAX
;) 请注意,此优化表明只有少数行具有极高的工资(这通常是这种情况 - 至少对于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")
Tried with postgresql用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 ) ;
o/p开/关
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.