当前位置: 首页 > 科技观察

如何在SQL面试中取胜?这些技巧和陷阱要知道...

时间:2023-03-14 14:50:43 科技观察

SQL是最基础的数据分析和处理编程语言之一,所以不管你是面试数据分析师、数据科学家、数据工程师,还是其他相关工作,你必然要过这一关。实践技术和解决问题的能力是SQL面试的重点。考生不仅要根据样本数据编写正确的查询,还要考虑各种场景和边缘情况,就像处理实际数据集一样。作者曾帮助求职者设计SQL面试题,模拟面试,并多次参与大型科技公司和初创企业的SQL求职面试实战。本文解释了SQL面试问题中的常见模式,并分享了在SQL查询中灵活处理这些模式的技巧。拿出你的小本子开始学习吧~提问要赢得SQL面试,最重要的是尽可能多地提问,以确保你掌握了给定任务和数据样本的所有细节。了解这些要求有助于节省迭代问题的时间,也有助于更好地处理边缘情况。许多候选人在没有深入了解SQL问题或数据集的情况下就直接开始解决问题。作者指出解决方案中的问题后,他们不得不反复修改查询,浪费大量时间迭代,最终甚至没有找到正确的解决方案。我的建议是将SQL面试视为与业务合作伙伴的合作,并且以这种心态,面试官将在提供解决方案之前尝试收集数据请求的所有要求。示例从下表中查找收入最高的三名员工。示例:员工薪资表面试官应该要求面试官详细说明“前三名”的概念——结果中必须只有三名员工吗?并行处理的要求是什么?另外,面试官要仔细查看样本员工的数据——salary字段的数据类型是什么?计算前需要清除数据吗?什么样的加盟?在SQL中,联接通常用于组合来自多个表的信息。有四种不同类型的连接,但在大多数情况下我们只使用自然连接、左连接和完全连接,因为右连接不直观并且很容易使用左连接重写。在SQL面试中,面试官需要根据给定问题的具体要求来选择正确的连接。示例查找每个学生已上课的总课程数。(学号、姓名、班级数已知。)样本:学生列表和课程数据表可以注意到,并非所有出现在课程数据表中的学生都出现在学生列表中,这可能是因为这些学生有毕业(这在事务数据库中非常典型,其中数据在不活动时被删除)。在知道面试官是否要包括不活跃的学生后,可以根据情况使用leftjoin和naturaljoin合并表。WITHclass_countAS(SELECTstudent_id,COUNT(*)ASnum_of_classFROMclass_historyGROUPBYstudent_id)SELECTc.student_id,s.student_name,c.num_of_classFROMclass_countc--CASE1:includeonlyactivestudentsJOINstudentsONc.student_id=s.student_id--CASE2:includeallstudents--LEFTJOINstudentsONc.student_id=s.student_idGROUPBYGROUPBY是SQL中最基本的功能,广泛用于数据聚合。如果SQL问题中出现sum、average、minimum或maximum等关键字,则很有可能应该在查询中使用GROUPBY。一个常见的陷阱是在使用GROUPBY过滤数据时将WHERE与HAVING混淆——许多人都会犯这个错误。该示例计算每个学生每个学年所需的GPA,并找到每个学期GPA≥3.5的学生。示例:GPA数据表在计算GPA时只考虑必修课,所以需要用WHEREis_required=TRUE排除选修课。需要计算每个学生每个学年的平均绩点,所以需要用GROUPBY命令对student_id和school_year两列进行分组,取gpa的平均值。最后,只保留平均GPA高于3.5的行,这可以通过HAVING来实现。然后结合上面的结果:SELECTstudent_id,school_year,AVG(gpa)ASavg_gpaFROMgpa_historyWHEREis_required=TRUEGROUPBYstudent_id,school_yearHAVINGAVG(gpa)>=3.5记住,每当你在查询中使用GROUPBY时,只能选择要分组的列,然后进行聚合因为其他列中的行级信息已被丢弃。可能有人会疑惑WHERE和HAVING有什么区别,或者为什么不直接使用avg_gpa>=3.5,而是指定function。下一节会给出详细的解释。SQL查询语句执行顺序大多数人在写SQL查询时,都是按照自上而下的顺序,但他们可能不知道SELECT是SQL引擎最后执行的函数之一。下面是SQL查询的执行顺序:FROM,JOINWHEREGROUPBYHAVINGSELECTDISTINCTORDERBYLIMIT,OFFSET回头看前面的例子。由于在计算GPA之前需要过滤掉electives,所以HAVING可以换成WHEREis_required=TRUE,因为WHERE在GROUPBY和HAVING之前执行。之所以不使用HAVINGavg_gpa>=3.5,是因为avg_gpa被定义为SELECT的一部分,所以不能在SELECT之前执行的步骤中引用。来源:unsplash作者建议按照执行顺序编写查询,这在编写复杂查询时非常有用。窗口函数窗口函数在SQL面试中也经常出现。五个常用的窗口函数如下:RANK/DENSE_RANK/ROW_NUMBER:通过对特定列进行排序,为每一行分配一个等级。如果给出任何分区列,行将排列在它们所属的分区组中。LAG/LEAD:按照指定的顺序和分区组从上一行或后一行中检索列值。在SQL面试中,面试官必须知道排名函数之间的区别以及何时使用LAG/LEAD。示例查找每个部门中收入最高的3名员工。示例:员工薪水表2当SQL题要求找出“topNnames”时,可以使用ORDERBY或ranking函数来回答。但是上面的例子需要计算“每个Y中的前N个X”,也就是说面试官要用ranking函数,因为需要对每个partitiongroup中的行进行排序。下面的查询能准确找到3名薪资最高的职员,不考虑并列:WITHTAS(SELECT*,ROW_NUMBER()OVER(PARTITIONBYdepartment_idORDERBYemployee_salaryDESC)ASrank_in_depFROMemployee_salary)SELECT*FROMTWHERErank_in_dep<=3--Note:WhenusingROW_NUMBER,eachrowwillhaveauniqueranknumberandranksfortiedrecordsareassignedrandomly.Forexmaple,RimshaandTiahmayberank2or3indifferentqueryruns.另外,根据面试官对处理平行情况的要求,面试官也可以选择不同的排序函数。再次提醒大家,细节很重要!ROW_NUMBER、RANK和DENSE_RANK这三个函数的比较。重复SQL面试中的另一个常见陷阱是忽略重复项。即使某些列在样本数据中看起来具有不同的值,访问者也应该像处理真实数据集一样考虑所有可能的场景。比如上面例子中的员工薪水表,不同的员工可能有相同的名字。避免由重复引起的潜在问题的一种简单方法是始终使用ID列来标识不同的记录并避免重复。示例根据员工工资表,查找所有部门每个员工的工资总和。正确的解决办法是按employee_id分组,用SUM(employee_salary)计算总工资。如果需要员工姓名,可以在末尾添加员工表单,获取员工姓名信息。按employee_name分组是错误的。NULL在SQL中,任何谓词都可能产生三个值之一:true、false和NULL。关键字NULL用于指代未知或丢失的数据。处理NULL可能很棘手。在SQL面试中,面试官在解题的时候会特别注意面试官是否处理了NULL。在某些情况下,很明显某一列的数据不能为NULL(比如ID列),但其他大部分列很可能会出现NULL。作者建议面试官确认样本数据中的关键列是否可以为空,如果可以,则使用IS(NOT)NULL、IFNULL和COALESCE等函数来覆盖这些边缘情况。还有一个很重要的沟通点就是保证面试过程中的沟通顺畅。我采访的许多求职者很少说话,除非他们真的有问题。如果他们最后能想出一个完美的解决方案,那很好,但在技术面试期间与面试官保持沟通通常会有所帮助。例如,面试官可以谈论他们对问题和数据的理解,他们计划如何解决问题,为什么他们使用一个功能而不是另一个,或者他们正在考虑的边缘情况。总结从提问开始,收集您需要的详细信息。仔细选择连接方式——自然连接、左连接或全连接。使用GROUPBY聚合数据,合理使用WHERE和HAVING。了解三个排名函数之间的差异。了解何时使用LAG/LEAD窗口函数。如果您需要创建的查询过于复杂,请尝试按照SQL执行的顺序编写。考虑潜在的数据问题,例如重复和空值。与面试官交流思考过程。面试很顺利!