176、第二高的薪水
(1)按照薪水降序进行排序
select * from Employee
order by Salary desc
发现降序排列后,Id值的顺序也乱了,本来还想选取降序排列后的第二个Id进行查询呢?看来需要换个思路:
增加有序的一列?
思路:
(1) 按照Salary降序查询
select * from Employee
order by Salary desc;
(2) 降序后发现id顺序变乱,故新增一列自增的字段new_id,以便于后续第二高薪水的查询
alter table (select * from Employee
order by Salary desc) a
add new_id int(4) not null primary key auto_increment first;
出现错误:原因应该是alter table后面应该是需要数据库里存在的一张表,而不是子查询的一张表。
(3) 根据new_id=2查询第二高薪水:
select Salary as SecondHighestSalary
from (alter table (select * from Employee
order by Salary desc) a
add new_id int(4) not null primary key auto_increment first)
where new_id=2;
但是这个思路有很多bug,比如重复值、空值都没有考虑
利用limit?
select Salary as SecondHighestSalary
from Employee
order by Salary desc
limit 1,1;
但是,没有考虑空值,提交报错.
利用ifnull()修改如下:
select ifnull((select Salary
from Employee
order by Salary desc
limit 1,1),null) as SecondHighestSalary;
但是没有考虑重复值(比如有两个相同值),利用distinct 继续修改如下
select ifnull((select distinct Salary
from Employee
order by Salary desc
limit 1,1),null) as SecondHighestSalary;
参考答案:
方法一:排除法:找到最大值,排除它,再找最大值
(1)找到最大值。
select max(Salary) from Employee;
(2)找到比最大值小的最大值。
select max(Salary) as SecondHighestSalary from Employee
where salary<
(select max(Salary) from Employee);
方法二:偏移法 limit offset
(1)对薪水降序排序,并偏移到第二个值
select * from Employee
order by Salary
limit 1
offset 1;
(2)记得去重,防止出现重复值影响结果
select distinct Salary as SecondHighestSalary from Employee
order by Salary
limit 1
offset 1;
(3)还需要考虑空值的情况
框架:
select ifnull((),null);
详细代码:
select ifnull((select distinct Salary from Employee
order by Salary
limit 1
offset 1) ,null) as SecondHighestSalary;
补充:
(a)mysql在现有表字段之前增加一列id,并赋值为自动递增
alter table 表名
add new_id int(4) not null primary key auto_increment first;
(b)删除字段
alter table 表 drop column 字段;
(c)更改记录
update Employee set Salary=200 where Id=2;