博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【LeetCode刷题】SQL-Second Highest Salary 及扩展以及Oracle中的用法
阅读量:6487 次
发布时间:2019-06-23

本文共 3265 字,大约阅读时间需要 10 分钟。

转载于:

Write a SQL query to get the second highest salary from the Employee table.

 

+----+--------+| Id | Salary |+----+--------+| 1  | 100    || 2  | 200    || 3  | 300    |+----+--------+

 

For example, given the above Employee table, the query should return 200 as the second highest salary. If there is no second highest salary, then the query should return null

+---------------------+| SecondHighestSalary |+---------------------+| 200                 |+---------------------+

 

 to see which companies asked this question.

 

翻译:

题目的意思是,在Employee表中找到第二大的Salary字段,然后以别名“SecondHighestSalary ”的形式输出

 

解题思路:

本题有两种思路。

一种是找到找到最大值,然后我们取比最大值小一点的最大值。

SQL:

SELECT Max(Salary) as SecondHighestSalary FROM Employee WHERE Salary< ( SELECT Max(Salary) FROM Employee);

 

函数表示返回最大值,如果没有最大值则返回。

Salary<( SELECT Max(Salary) FROM Employee) 则是子查询的概念。

例如 Select * From Table_A Where key in (a,b);  如果其中(a,b)的数据来源于Table_B或者Table_A表。我们就可以使用子查询,将(a,b)的数据替换为我们查询到的数据。

Select * From Table_A Where key in (Select a,b From Table_B  Where Inr='XXXXXXX');

“as XXX”则表示将输出的数据以“XXX”为别名的方式输出。

 

还有一种方法就是,我们将数据进行排序,然后取第二位数。

这种方法的难点在于:1、数据可能会有重复项。

          2、需要先排序再取数,所以不能用between 方法因为between方法必须要在order by 之前。

          3、整个表都是同一个数据的极端情况。

对于情况3容易产生的错误写法:

select Salary SecondHighestSalary from employee order by salary limit 1,1

 

  要解决以上3个难点。我们首先使用DISTINCT方法将数据的重复项过滤只剩一条,然后使用LIMIT分页的方法取第二个值,对于情况3中的极端情况,我们使用来进行判断,如果没取到值就返回NULL。

  需要注意的是,LIMIT是MySQL中的用法,Oracle是不支持LIMIT的。

SQL:

SELECT IFNULL( (SELECT distinct Salary  FROM Employee order by Salary desc limit 1,1),null)as SecondHighestSalary;

其中LIMIT 的用法是这样的:

LIMIT m,n      "m"表示偏移量,表示从第几位开始取。"n"表示长度,即需要取多少位。

  需要注意的是偏移量的第一位为0,所以"LIMIT 1,1"表示从第二位开始取长度为1的数也就是第二位数。

  "LIMIT 0,n"或者"LIMIT n "则表示从第一位开始取,一直取到第n位为止。"LIMIT m,-1"表示从第m位开始取,一直取到表的末尾。

  distinct 表示将查询到的结果过滤重复项,只保留一项。

IFNULL(Exp1,Exp2),类似一个三元表达式,如果Exp1不为空则返回Exp1的结果集,如果为空就返回Exp2.

 

方法二的关键点在于排序和取数,排序我们除了使用ORDER BY 方法之外,还可以使用比较的方式排序。

SQL:

SELECT DISTINCT(e2.Salary) FROM Employee e1,Employee e2 WHERE e2.Salary>=e1.Salary;

使用“>=”的方式,是为了。

sql空值表示:

在允许空值的情况下,空值是NULL(null在表中为字符串类型),指没有填写过数据;

在不允许为空的情况下,数值型字段默认为0)

需要注意的是,这种排序方式非常非常的消耗系统资源,在实际生产中使用这种方式来排序是不负责任的行为(见),所以如非必要尽量不要使用这种方式而使用更快捷消耗更小的的Order by。

现在已经排好序了,那么接下来我们要进行取数。取数可以使用上面的LIMIT方法。

LIMIT方法:

SELECT IFNULL((SELECT DISTINCT(e2.Salary) FROM Employee e1,Employee e2 WHERE e2.Salary>e1.Salary LIMIT 1,1),NULL) as SecondHighestSalary;

即,将:order by Salary desc 替换为 WHERE e2.Salary>e1.Salary 

除此之外还有其他方法吗?我们知道,SELECT语句实际上是个循环语句,既然是个循环语句而且已经排好序,那么也就是说如果我们要取第二大的数据,我们可以取当他循环到第二次时的那一行。怎么取到那一行呢。学过For循环都知道,要先对这个循环进行计数,然后循环到我们需要的那一次再取值。那么SQL中怎么计数呢。答案是使用COUNT方法。

COUNT方法

SELECT e1.Salary FROM Employee e1 WHERE 2=(Select Count(distinct(e2.Salary)) from Employee e2 where e2.Salary >= e1.Salary) as SecondHighestSalary;

上面两种方法也可以用于,取任意第N位数据时。

COUNT方法之所以不能使用Order by,是因为Order by是对结果进行排序,而我们需要的是已排序好的结果。

 如果要使用Order by 方法,需要再加一层子查询。

COUNT-Order By 方法

SELECT Salary FROM Employee  WHERE 2=(Select Count(distinct(Salary)) from (Select Salary From Employee order by Salary desc)) as SecondHighestSalary;

.

由于Oracle中不能使用LIMIT,所以我们用rownum来处理此问题

Select Salary from (select amt ,rownum n From (Select distinct amt from Employee order by Salary desc)) where n=2;

其中的n=2可以替换为任意正整数,即为第N位。

总结:对一个题可以通过不同角度思考并优化解答,这需要长期不断地积累各种知识点并汇总结合

 

转载于:https://www.cnblogs.com/MarsDing/p/9870715.html

你可能感兴趣的文章
PC散热风扇之研究一:风扇种类介绍
查看>>
关于Session和Cookie简单实例
查看>>
App框架实现———dagger2
查看>>
zabbix 微信报警
查看>>
通过SQL Server 2008数据库复制实现数据库同步备份
查看>>
HttpClient做接口测试时自定义参数长度
查看>>
PyCharm2017激活方法
查看>>
正则表达式
查看>>
Exchange企业实战技巧(27)邮件中使用数字签名和邮件加密功能
查看>>
mysql-5.6.27源码安装及错误解决办法
查看>>
Shell 函数、数组与正则表达式
查看>>
编译安装PHP时两个报错的解决办法
查看>>
System Center 2012 SP1 Data Protection Manager 防止重复备份数据
查看>>
软考复习之路——软考总结
查看>>
Kali linux 2016.2(Rolling)里Metasploit的常用模块
查看>>
企业项目开发--企业中的项目架构以及多环境分配(1)
查看>>
C++语言基础(19)-模板的显式具体化
查看>>
深入理解JavaScript系列(18):面向对象编程之ECMAScript实现
查看>>
如何改变Android tab 的高度和字体大小
查看>>
hdu 2853
查看>>