行业动态

防御吧作为15年知名老牌域名服务商,CNNIC和CANN双认证域名注册商,已经
持续为500多万个域名提供服务,包括智能DNS/自由转移/隐私保护等服务!
数据科学家常见的5个SQL面试问题
2020-02-28 14:42:29 【
在任何以数据为中心的工作中,对SQL有深刻的理解都是成功的关键,尽管这不是工作中最有趣的部分。事实上,除了SELECT FROM WHERE GROUP BY ORDER BY之外,还有更多的SQL方法。你知道的功能越多,操作和查询所需的内容就越容易。
作者希望在本文中学习和交流以下两件事:
1)学习和教一些基本功能以外的SQL函数;
2)探讨一些SQL面试练习问题。
* 本文中的问题仅来自Leetcode

问题1:第二高的薪水


编写一个SQL查询用于从Employee表中获取第二高的薪水。例如,给定下面的Employee表,查询应返回200作为第二高的薪水。如果没有第二高的薪水,则查询应返回null。







+----+--------+| Id | Salary |+----+--------+|1| 100     || 2   |200||3| 300     |+----+--------+
1)解决方案A使用IFNULLOFFSET
  • IFNULL(表达,alt):如果为null,则ifnull()返回指定的值,否则返回期望的值。 如果没有第二高的薪水,我们会使用它返回null。
  • OFFSET:offset与ORDERBY子句一起使用可忽略指定的前n行。这会很有用,因为你希望获得第二行(第二高的薪水)






| Id | Salary |+----+--------+|1| 100     || 2   |200||3| 300     |+----+--------+
2)解决方案B使用MAX()
此查询表示选择的MAX薪水不等于最高薪水,这等于选择第二高的薪水。









SELECTIFNULL((SELECT DISTINCT SalaryFROM EmployeeORDERBY Salary DESCLIMIT 1 OFFSET 1), null) as SecondHighestSalaryFROM EmployeeLIMIT 1


问题2:重复的电子邮件


编写SQL查询以在名为Person的表中查找所有重复的电子邮件。







+----+---------+| Id | Email    |+----+---------+| 1  | a@b.com  || 2  | c@d.com  || 3  | a@b.com  |+----+---------+
1)解决方案A子查询中的COUNT()
首先,创建一个子查询来显示每封电子邮件的频率次数。然后子查询在计数大于1的地方被过滤。







SELECT EmailFROM (SELECT Email, count(Email) AS countFROM PersonGROUP BY Email) as email_countWHERE count > 1
2)解决方案B:HAVING子句
  • HAVING是一个子句,从本质上讲,你可以将WHERE语句与聚合(GROUP BY)结合使用。




SELECT EmailFROM PersonGROUP BY EmailHAVING count(Email) > 1

问题3:温度上升


下面给定一个天气表,编写一个SQL查询来查找与其之前(昨天)日期相比温度更高的所有日期的ID。








+---------+------------------+------------------+| Id(INT) | RecordDate(DATE) | Temperature(INT) |+---------+------------------+------------------+|         1 | 2015-01-01         | 10                   ||         2 | 2015-01-02         | 25                   ||         3 | 2015-01-03         | 20                   ||         4 | 2015-01-04         | 30                   |+---------+------------------+------------------+
解决方案:DATEDIFF()
  • DATEDIFF是计算两个日期之间的差,用于确保我们将今天的温度与昨天的温度进行比较。

简单来说,查询是选择给定日期的温度高于昨天的温度的ID。





SELECT DISTINCT a.IdFROM Weather a, Weather bWHERE a.Temperature > b.TemperatureAND DATEDIFF(a.Recorddate, b.Recorddate) = 1

问题4:部门最高薪资


下面的雇员表中包含所有雇员。每个员工都有一个ID、一个薪水,还有一个部门ID列。









+----+-------+--------+--------------+| Id | Name   | Salary | DepartmentId |+----+-------+--------+--------------+| 1   | Joe   | 70000  | 1               || 2   | Jim   | 90000  | 1               || 3   | Henry | 80000  | 2               || 4   | Sam   | 60000  | 2               || 5   | Max   | 90000  | 1               |+----+-------+--------+--------------+
下面的部门表包含公司的所有部门。






+----+----------+| Id | Name      |+----+----------+| 1   | IT        || 2   | Sales    |+----+----------+
编写SQL查询来查找每个部门中薪水最高的员工。对于上述两个表,你的SQL查询应返回以下行(行的顺序无关紧要)。







+------------+----------+--------+| Department | Employee | Salary |+------------+----------+--------+| IT            | Max       | 90000  || IT            | Jim       |90000   || Sales        | Henry     | 80000  |+------------+----------+--------+
解决方案:IN子句
  • IN子句允许你在WHERE语句中使用多个OR子句。例如,WHERE country ='Canada'或country ='USA'与WHERE country IN('Canada','USA')相同。

  • 在这种情况下,我们希望过滤部门表来仅显示每个部门的最高薪水(即DepartmentId)。然后,我们可以将两个表连接在一起,其中DepartmentId和Salary在已过滤的Department表中。















SELECTDepartment.name AS 'Department',Employee.name AS 'Employee',SalaryFROM EmployeeINNER JOIN Department ON Employee.DepartmentId = Department.IdWHERE (DepartmentId , Salary)IN( SELECTDepartmentId, MAX(Salary)FROMEmployeeGROUP BY DepartmentId)

问题5:互换座位


玛丽是一所中学的老师,她有一张座位表,上面存储着学生的姓名和相应的座位ID。列ID是连续的增量,玛丽想为相邻的学生互换座位。
你可以编写SQL查询来输出玛丽的结果吗?









+---------+---------+|    id     | student |+---------+---------+|    1      | Abbot   ||    2      | Doris   ||    3      | Emerson ||    4      | Green   ||    5      | Jeames  |+---------+---------+
对于样本输入,输出为:









+---------+---------+|    id     | student |+---------+---------+|    1      | Doris   ||    2      | Abbot   ||    3      | Green   ||    4      | Emerson ||    5      | Jeames  |+---------+---------+
注意:如果学生人数为奇数,则无需更改最后一个座位。
解决方案:CASE WHEN
  • 可以将CASE WHEN THEN语句视为编码中的IF语句。
  • 第一条WHEN语句检查行数是否为奇数,如果行数为奇数,请确保ID号不变。
  • 第二个WHEN语句为每个id加1(例如,1,3,5变为2,4,6)
  • 同样,第三个WHEN语句将每个id减1(2,4,6变为1,3,5)








SELECTCASEWHEN((SELECT MAX(id) FROM seat)%2 = 1) AND id = (SELECT MAX(id) FROM seat) THEN idWHEN id%2 = 1 THEN id + 1ELSE id - 1END AS id, studentFROM seatORDERBYid
以上就是所有的解决方法,如果有不清楚的地方或其他意见,欢迎评论告诉我们!


】【打印关闭】 【返回顶部
分享到QQ空间
分享到: 
上一篇隐藏Windows文件扩展名存在安全风.. 下一篇Apache Dubbo反序列化漏洞(CVE-2..

立足首都,辐射全球,防御吧专注云防御及云计算服务15年!

联系我们

服务热线:13051179500 18910191973
企业QQ:1245940436
技术支持:010-56159998
E-Mail:xihedata.com
Copyright ? 2003-2016 fangyuba. 防御吧(完美解决防御与加速) 版权所有 增值许可:京B2-20140042号
售前咨询
公司总机:18910191973
24小时电话:010-56159998
投诉电话:18910191973
值班售后/技术支持
售后服务/财务
备案专员
紧急电话:18610088800