前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >数据科学家常见的5个SQL面试问题

数据科学家常见的5个SQL面试问题

作者头像
博文视点Broadview
发布2020-06-12 17:17:01
1.3K0
发布2020-06-12 17:17:01
举报

在任何以数据为中心的工作中,对SQL有深刻的理解都是成功的关键,尽管这不是工作中最有趣的部分。事实上,除了SELECT FROM WHERE GROUP BY ORDER BY之外,还有更多的SQL方法。你知道的功能越多,操作和查询所需的内容就越容易。

本文中将与大家学习和交流以下两件事:

1)学习和教一些基本功能以外的SQL函数

2)探讨一些SQL面试练习问题

* 本文中的问题仅来自Leetcode

问题1:第二高的薪水

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

代码语言:javascript
复制
+----+--------+
| Id | Salary |
+----+--------+
| 1   | 100     |
| 2   | 200     |
| 3   | 300     |
+----+--------+

1)解决方案A:使用IFNULL,OFFSET

  • IFNULL(表达,alt):如果为null,则ifnull()返回指定的值,否则返回期望的值。 如果没有第二高的薪水,我们会使用它返回null。
  • OFFSET:offset与ORDERBY子句一起使用可忽略指定的前n行。这会很有用,因为你希望获得第二行(第二高的薪水)
代码语言:javascript
复制
SELECT
IFNULL(
(SELECT DISTINCT Salary
FROM Employee
ORDER BY Salary DESC
LIMIT 1 OFFSET 1
), null) as SecondHighestSalary
FROM Employee
LIMIT 1

2)解决方案B:使用MAX()

此查询表示选择的MAX薪水不等于最高薪水,这等于选择第二高的薪水。

代码语言:javascript
复制
SELECT MAX(salary) AS SecondHighestSalary
FROM Employee
WHERE salary != (SELECT MAX(salary) FROM Employee)

问题2:重复的电子邮件

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

代码语言:javascript
复制
+----+---------+
| Id | Email    |
+----+---------+
| 1  | a@b.com  |
| 2  | c@d.com  |
| 3  | a@b.com  |
+----+---------+

1)解决方案A:子查询中的COUNT()

首先,创建一个子查询来显示每封电子邮件的频率次数。然后子查询在计数大于1的地方被过滤。

代码语言:javascript
复制
SELECT Email
FROM (
SELECT Email, count(Email) AS count
FROM Person
GROUP BY Email
) as email_count
WHERE count > 1

2)解决方案B:HAVING子句

  • HAVING是一个子句,从本质上讲,你可以将WHERE语句与聚合(GROUP BY)结合使用。
代码语言:javascript
复制
SELECT Email
FROM Person
GROUP BY Email
HAVING count(Email) > 1

问题3:温度上升

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

代码语言:javascript
复制
+---------+------------------+------------------+
| 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。

代码语言:javascript
复制
SELECT DISTINCT a.Id
FROM Weather a, Weather b
WHERE a.Temperature > b.Temperature
AND DATEDIFF(a.Recorddate, b.Recorddate) = 1

问题4:部门最高薪资

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

代码语言:javascript
复制
+----+-------+--------+--------------+
| Id | Name   | Salary | DepartmentId |
+----+-------+--------+--------------+
| 1   | Joe   | 70000  | 1               |
| 2   | Jim   | 90000  | 1               |
| 3   | Henry | 80000  | 2               |
| 4   | Sam   | 60000  | 2               |
| 5   | Max   | 90000  | 1               |
+----+-------+--------+--------------+

下面的部门表包含公司的所有部门。

代码语言:javascript
复制
+----+----------+
| Id | Name      |
+----+----------+
| 1   | IT        |
| 2   | Sales    |
+----+----------+

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

代码语言:javascript
复制
+------------+----------+--------+
| 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表中。
代码语言:javascript
复制
SELECT
Department.name AS 'Department',
Employee.name AS 'Employee',
Salary
FROM Employee
INNER JOIN Department ON Employee.DepartmentId = Department.Id
WHERE (DepartmentId , Salary)
IN
( SELECT
DepartmentId, MAX(Salary)
FROM
Employee
GROUP BY DepartmentId
)

问题5:互换座位

玛丽是一所中学的老师,她有一张座位表,上面存储着学生的姓名和相应的座位ID。列ID是连续的增量,玛丽想为相邻的学生互换座位。

你可以编写SQL查询来输出玛丽的结果吗?

代码语言:javascript
复制
+---------+---------+
|    id     | student |
+---------+---------+
|    1      | Abbot   |
|    2      | Doris   |
|    3      | Emerson |
|    4      | Green   |
|    5      | Jeames  |
+---------+---------+

对于样本输入,输出为:

代码语言:javascript
复制
+---------+---------+
|    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)
代码语言:javascript
复制
SELECT
CASE
WHEN((SELECT MAX(id) FROM seat)%2 = 1) AND id = (SELECT MAX(id) FROM seat) THENid
WHEN id%2 = 1 THEN id + 1
ELSE id - 1
END AS id, student
FROM seat
ORDER BY id

以上就是所有的解决方法。

(作者 | Alexei Ledenev,翻译 | 天道酬勤,责编 | Carol)

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-03-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 博文视点Broadview 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档