2022-10-27 301
SQL是数据分析和处理最基本的编程语言之一,因此,无论是面试数据分析师、数据科学家、数据工程师,还是其他相关工作,都免不了要过这一关。
实战技术和解决问题的能力是SQL面试中考察的重点,应聘者不仅要基于示例数据编写正确的查询,还要考虑各种场景和边缘情况,就如同在处理实际数据集。
笔者曾经帮助求职者设计过SQL面试问题,并模拟了面试,也多次亲身参加了大型科技公司和初创企业SQL求职面试的实战。本文将对SQL面试问题的常见模式进行阐释,分享在SQL查询中灵活处理这些模式的技巧。
快掏出小本本开始学习吧~
提问
要拿下一场SQL面试,最重要的在于尽可能多地提问,以确保自己掌握了给定任务和数据样本的所有细节。理解这些需求有助于节省迭代问题的时间,也有助于更好地处理边缘情况。
许多应聘者会在没有深入理解SQL问题或数据集之前,直接开始解决问题。在笔者指出解决方案中的问题之后,他们不得不反复修改查询,在迭代上浪费了大量时间,甚至到最后都没找到正确的解决方案。
笔者的建议是将SQL面试视为在与业务合作伙伴一起工作,保持这种心态,面试者就会在提供解决方案之前努力收集数据请求的所有需求。
示例
从下表中找出薪资最高的三位职员。
样本:职员薪资表
面试者应该让面试官仔细阐述“前三名”的概念——结果中必须只有三名职员吗?对于并列的处理有何要求?此外,面试者应仔细查看示例职员的数据——薪资字段的数据类型是什么?需要在计算之前清除数据吗?
何种连接
在SQL中,连接经常用于组合来自多个表的信息。共有四种不同类型的连接,但是在大多数情况下,我们只使用自然连接、左连接和全连接,因为右连接并不直观,而且使用左连接很容易重写。在SQL面试中,面试者需要根据给定问题的特定要求,选择正确的连接。
示例
找出每位学生上课的总节数。(已知学生证、姓名和上课次数。)
样本:学生名单和课程数据表
可以注意到,并非所有出现在课程数据表中的学生都存在于学生名单中,这可能是因为这些学生已经毕业(这在事务数据库中非常典型,数据不活跃时就会被删除)。在了解清楚面试官是否希望将不活跃的学生包括在内之后,可以根据情况使用左连接和自然连接两种方式来合并表格。
WITHclass_countAS( SELECTstudent_id,COUNT(*)ASnum_of_class FROMclass_history GROUPBYstudent_id ) SELECT c.student_id, s.student_name, c.num_of_class FROMclass_countc --CASE1:includeonlyactivestudents JOINstudentsONc.student_id=s.student_id--CASE2:includeallstudents --LEFTJOINstudentsONc.student_id=s.student_id
GROUP BY
GROUP BY是SQL中最基本的函数,广泛用于数据聚合。如果在一个SQL问题中出现了sum、average、minimum或maximum等关键字,则极有可能应该在查询中使用GROUP BY。一个常见的陷阱是,在用GROUP BY过滤数据时将WHERE和HAVING混淆——许多人都犯过这个错误。
示例
计算每个学生每学年的必修课平均绩点,并找出每学期中绩点≥3.5的学生。
样本:GPA数据表
在计算GPA时只考虑必修课,因此需要使用 WHERE is_required = TRUE来排除选修课。需要计算每个学生每学年的平均绩点,因此需要用GROUP BY命令按student_id 和school_year 两列来进行分组,并取gpa的平均值。最后,只保留平均GPA高于3.5的行,这可以通过HAVING实现。再将以上所得进行结合:
SELECT student_id, school_year, AVG(gpa)ASavg_gpa FROMgpa_history WHEREis_required=TRUE GROUPBYstudent_id,school_year HAVINGAVG(gpa)>=3.5
记住,无论何时在查询中使用GROUP BY,都只能选择要分组的列,然后进行聚合,因为其他列中的行级信息已被丢弃。
可能有人想知道WHERE和HAVING之间有什么区别,或者想知道为什么不直接用avg_gpa>= 3.5,而是指定函数。下一节将会给出详细解释。
SQL查询语句执行顺序
在写SQL查询时,大多数人是按照自上而下的顺序,但他们可能并不知道SELECT是SQL引擎最后执行的函数之一。以下是SQL查询的执行顺序:
回头再看前面的示例。因为需要在计算平均绩点之前过滤掉选修课,所以可以用 WHERE is_required = TRUE来代替HAVING,因为WHERE在GROUP BY和HAVING之前执行。不用HAVINGavg_gpa >= 3.5的原因是avg_gpa被定义为SELECT的一部分,所以不能在SELECT之前执行的步骤中引用。
图源:unsplash
笔者建议在编写查询时按照执行顺序编写,这在编写复杂查询时非常有用。
窗口函数
窗口函数也经常出现在SQL面试中。五种常见的窗口函数如下:
在SQL面试中,面试者必须知道排名函数之间的差异,以及何时使用LAG/LEAD。
示例
找出每个部门中薪资最高的3名职员。
样本:职员薪资表2
当SQL问题要求找出“前N名”时,可以使用ORDER BY或ranking函数来回答。但以上示例要求计算“每个Y中的前N 个X”,这代表着面试者应该使用排ranking函数,因为需要对每个分区组中的行进行排列。
下面的查询能准确找到3名薪资最高的职员,不考虑并列:
WITHTAS( SELECT *, ROW_NUMBER()OVER(PARTITIONBYdepartment_idORDERBYemployee_salaryDESC)ASrank_in_dep FROMemployee_salary) SELECT*FROMT WHERErank_in_dep<=3--Note:WhenusingROW_NUMBER,eachrowwillhaveauniqueranknumberandranksfortiedrecordsareassignedrandomly.Forexmaple,RimshaandTiahmayberank2or3indifferentqueryruns.
另外,根据面试官对并列情况处理的要求,面试者也可选择不同的ranking函数。再次提醒大家,细节很重要!
ROW_NUMBER、RANK和 DENSE_RANK 三种函数的对比。
重复项
SQL面试中的另一个常见陷阱是忽略重复项。尽管有些列在示例数据中似乎具有不同的值,但面试者还是应该考虑所有可能的情况,就像在处理真实的数据集一样。例如,在上例的员工薪资表中,不同职员可能出现同名情况。
想要避免重复项引起的潜在问题,一个简单的方法是始终使用ID列来标识不同的记录,避免重复。
示例
根据职员薪资表,找出所有部门每个职员的总工资。
正确的解决方案是按employee_id 来分组,使用SUM(employee_salary)来计算总薪资。如果需要员工姓名,可在末尾加入职员表格来检索职员的姓名信息。
用employee_name来分组是错误的。
NULL
在SQL中,任何谓词都可能产生以下三个值之一:true、false和NULL。NULL这一关键词用于指代未知或空缺数据。处理NULL可能会非常棘手。在SQL面试中,面试官会特别注意面试者在解决过程中是否处理了NULL。在一些情况下,很明显某列数据不能为空值(例如ID列),但大多数其他的列很可能会出现NULL。
笔者建议面试者确认示例数据中的关键列是否可以为空值,如果可以,则可以使用IS (NOT) NULL、IFNULL和COALESCE 等函数来覆盖这些边缘情况。
沟通
另外很重要的一点在于——在面试过程中保证流畅的沟通。
在笔者面试过的求职者中的很多人,除非真的有问题,否则几乎不说话。如果他们能在最后给出完美的解决方案,那倒也没什么大问题,但在技术面试中保持与面试者的沟通通常会有所助益。例如,面试者可以谈论自己对问题和数据的理解、自己是如何计划解决问题的、使用这个函数而不是另外一个的原因、或者正在考虑的边缘情况。
总结
面试顺利冲鸭!
原文链接:https://77isp.com/post/9828.html
=========================================
https://77isp.com/ 为 “云服务器技术网” 唯一官方服务平台,请勿相信其他任何渠道。
数据库技术 2022-03-28
网站技术 2022-11-26
网站技术 2023-01-07
网站技术 2022-11-17
Windows相关 2022-02-23
网站技术 2023-01-14
Windows相关 2022-02-16
Windows相关 2022-02-16
Linux相关 2022-02-27
数据库技术 2022-02-20
抠敌 2023年10月23日
嚼餐 2023年10月23日
男忌 2023年10月22日
瓮仆 2023年10月22日
簿偌 2023年10月22日
扫码二维码
获取最新动态