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

尽管对于SQL专家来说,编译SQL查询并不是最有趣的事情,但是对想要成功完成与数据处理相关的任何活动的人来说,对SQL的良好理解至关重要。这里的关键是,SQL不仅是SELECTFROMWHERE专家了解的SQL构造越多,他就越容易创建从数据库获取他可能需要的所有内容的请求。 该文章的作者(我们今天将要翻译的译本)说,其目的是解决两个问题:





  1. 探索超越基本SQL知识的机制。
  2. 考虑使用SQL的一些实际任务。

本文介绍了来自Leetcode的5个SQL问题。它们代表了面试中经常遇到的实际任务。

问题一:薪金第二


编写一个SQL查询,以从具有员工薪水信息(Employee)的表中获取包含第二高薪水的条目。

例如,为下表执行的查询应返回200如果表格的值不低于最高薪水,则请求应返回null

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

▍决定A:使用IFNULLOFFSET


以下是此问题解决方案中将使用的主要机制:

  • IFNULL(expression, alt)expression如果不相等,则此函数返回其参数null否则,返回参数altnull如果表不包含所需的值,我们将使用此函数返回
  • OFFSET:此运算符与表达式ORDER BY一起使用以舍弃前n几行。这对我们很有用,因为我们对结果的第二行(即第二高的薪水,表中的数据)感兴趣。

这是一个现成的请求:

SELECT
    IFNULL(
        (SELECT DISTINCT Salary
        FROM Employee
        ORDER BY Salary DESC
        LIMIT 1 OFFSET 1
        ), null) as SecondHighestSalary
FROM Employee
LIMIT 1

▍解决方案B:使用 MAX


下面的查询使用功能MAX在此,选择最高薪水值,该值不等于整个表格中收到的最高薪水。结果,我们得到了我们所需要的-第二大薪水。

SELECT MAX(salary) AS SecondHighestSalary
FROM Employee
WHERE salary != (SELECT MAX(salary) FROM Employee)

问题2:重复的电子邮件地址


编写一个SQL查询来检测表中Person所有重复的电子邮件地址。

+----+---------+
| Id | Email   |
+----+---------+
| 1  | a@b.com |
| 2  | c@d.com |
| 3  | a@b.com |
+----+---------+

▍决策A:COUNT在子查询中


首先,我们创建一个子查询,在其中确定表中每个地址的出现频率。然后,使用指令过滤子查询返回的结果WHERE count > 1该查询将多次返回有关在源表中找到的地址的信息。

SELECT Email
FROM (
    SELECT Email, count(Email) AS count
    FROM Person
    GROUP BY Email
) as email_count
WHERE count > 1

▍解决方案B:表达 HAVING


  • HAVING:这是一个表达式,允许您将指令WHERE与表达式一起使用GROUP BY

SELECT Email
FROM Person
GROUP BY Email
HAVING count(Email) > 1

问题三:温度上升


编写一个SQL查询,以在表中查找Weather温度高于其前日期温度的所有日期(日期标识符)。也就是说,我们对“今天”温度高于“昨天”温度的日期感兴趣。

+---------+------------------+------------------+
| 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:此函数计算两个日期之间的时差。它用于提供精确的“今天”和“昨天”温度的比较。

如果我们用普通语言来表达以下查询,结果表明它表达了以下思想:我们需要选择标识符,使得与它们表示的日期相对应的温度大于针对它们的“昨天”日期的温度。

SELECT DISTINCT a.Id
FROM Weather a, Weather b
WHERE a.Temperature > b.Temperature
AND DATEDIFF(a.Recorddate, b.Recorddate) = 1

问题4:单位中的最高薪水


该表Employee存储有关公司员工的信息。该表中的每个条目均包含有关该Id员工的标识符(),其姓名(Name),工资(Salary)以及其工作所在的公司部门(Department)的信息。

+----+-------+--------+--------------+
| Id | Name  | Salary | DepartmentId |
+----+-------+--------+--------------+
| 1  | Joe   | 70000  | 1            |
| 2  | Jim   | 90000  | 1            |
| 3  | Henry | 80000  | 2            |
| 4  | Sam   | 60000  | 2            |
| 5  | Max   | 90000  | 1            |
+----+-------+--------+--------------+

该表Department包含有关公司部门的信息。

+----+----------+
| Id | Name     |
+----+----------+
| 1  | IT       |
| 2  | Sales    |
+----+----------+

编写一个SQL查询,该查询在每个员工部门中找到最高薪水。例如,对于上面的表,类似的查询应返回由下表表示的结果(表中行的顺序无关紧要):

+------------+----------+--------+
| Department | Employee | Salary |
+------------+----------+--------+
| IT         | Max      | 90000  |
| IT         | Jim      | 90000  |
| Sales      | Henry    | 80000  |
+------------+----------+--------+

▍解决方案:团队 IN


该命令IN允许您在指令WHERE中设置与使用多个命令相对应的条件OR例如,以下两个构造是相同的:

WHERE country = ‘Canada’ OR country = ‘USA’
WHERE country IN (‘Canada’, ’USA’).

在这里,我们要获得一个包含部门名称(Department),雇员名称(Employee)和他的工资(Salary的表格为此,我们创建了一个表格,其中包含有关单位标识符(DepartmentID)和该单位最高工资的信息。然后,我们根据只有在结果表秋天哪个条目在条件表将二者结合起来DepartmentID,并Salary以前在表中形成的。

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:移植学生


玛丽是高中老师。她有一个表格seat,用于存储学生的姓名以及他们在教室中的位置信息。id表中的值不断增加。玛丽想交换邻居学生。

这是学生最初的位置表格:

+---------+---------+
|    id   | student |
+---------+---------+
|    1    | Abbot   |
|    2    | Doris   |
|    3    | Emerson |
|    4    | Green   |
|    5    | Jeames  |
+---------+---------+

移植附近的学生后,应该发生以下情况:

+---------+---------+
|    id   | student |
+---------+---------+
|    1    | Doris   |
|    2    | Abbot   |
|    3    | Green   |
|    4    | Emerson |
|    5    | Jeames  |
+---------+---------+

编写请求,使老师能够解决上述问题。

请注意,如果学生人数为奇数,则无需将最后一个学生转移到任何地方。

▍解决方案:使用运算符 WHEN


SQL构造CASE WHEN THEN可以视为if编程中的运算符

在我们的情况下,第一个运算符WHEN用于检查是否将奇数标识符分配给表的最后一行。如果是这样,则该行不会更改。第二个运算符WHEN负责对每个奇数标识符加1(例如,将1、3、5变成2、4、6),并从每个偶数标识符中减去1(将2、4、6变成1、3、5)。

SELECT 
    CASE 
        WHEN((SELECT MAX(id) FROM seat)%2 = 1) AND id = (SELECT MAX(id) FROM seat) THEN id
        WHEN id%2 = 1 THEN id + 1
        ELSE id - 1
    END AS id, student
FROM seat
ORDER BY id

摘要


我们研究了几个SQL任务,并一路讨论了一些可用于编译SQL查询的高级工具。我们希望您今天所学的内容在SQL访谈中对您有所帮助,并在日常工作中证明是有用的。

PS在我们的市场上,有一个带有SQL Server Express的Docker映像,只需单击一下即可安装。您可以在VPS上检查容器的操作。所有新客户均可免费享受3天的测试。

亲爱的读者们!对于那些想精通创建SQL查询的技巧的人,您能提供什么建议?

Source: https://habr.com/ru/post/undefined/


All Articles