破解面试难题8个角度带你解读SQL面试技巧!
作者 |?Xinran Waibel
譯者 | 天道酬勤?責(zé)編 | 徐威龍
封圖|?CSDN 下載于視覺中國(guó)
SQL是用于數(shù)據(jù)分析和數(shù)據(jù)處理的最重要的編程語言之一,因此SQL問題始終是與數(shù)據(jù)科學(xué)相關(guān)工作(例如數(shù)據(jù)分析師、數(shù)據(jù)科學(xué)家和數(shù)據(jù)工程師)面試過程中的一部分。? SQL面試旨在評(píng)估應(yīng)聘者的技術(shù)和解決問題的能力。因此,至關(guān)重要的是,不僅要根據(jù)樣本數(shù)據(jù)編寫正確的查詢語句,而且還要像對(duì)待現(xiàn)實(shí)數(shù)據(jù)集一樣考慮各種情況和極端情況。
作者曾幫助設(shè)計(jì)和執(zhí)行針對(duì)數(shù)據(jù)科學(xué)面試者的SQL面試問題,并親自為大型技術(shù)公司和初創(chuàng)公司進(jìn)行了許多SQL面試。在這篇文章中,作者將解釋SQL面試問題中常見的模式,并提供有關(guān)如何在SQL查詢中巧妙處理它們的技巧。
?
詢問問題
?
要搞定SQL面試,最重要的是通過詢問所需的盡可能多的問題來確保擁有給定任務(wù)和數(shù)據(jù)樣本的所有詳細(xì)信息。理解需求可以節(jié)省你以后迭代問題的時(shí)間,并使你能夠很好地處理極端情況。?
我注意到許多面試候選者往往不了解SQL問題或數(shù)據(jù)集就直接進(jìn)入解決方案。后來,在我指出解決方案中的問題之后,他們不得不重復(fù)修改查詢。最后,他們?cè)诘欣速M(fèi)了很多面試時(shí)間,甚至可能還沒有找到正確的解決方案。
我建議將SQL面試視作你正在與業(yè)務(wù)合作伙伴一起工作。在提供解決方案之前,你希望收集對(duì)數(shù)據(jù)請(qǐng)求的所有要求。
例如:查找薪水最高的前3名員工。? ? ??
?
employee_salary示例表
你應(yīng)要求面試官解釋清楚“前三名”的含義。我應(yīng)該在結(jié)果中包括3名員工嗎?你要我如何處理關(guān)系?此外,請(qǐng)仔細(xì)查看樣本員工數(shù)據(jù)。薪水字段的數(shù)據(jù)類型是什么?在計(jì)算之前是否需要清除數(shù)據(jù)?
?
哪個(gè)JOIN?
? ? ? ? ? ? ?
資料來源:MindMajix
在SQL中,JOIN通常用于合并來自多個(gè)表的信息。有四種不同類型的JOIN,但是在大多數(shù)情況下,我們僅使用INNER、LEFT和FULL JOIN,因?yàn)镽IGHT JOIN不是很直觀,可以使用LEFT JOIN輕松地重寫。在SQL面試中,你需要根據(jù)給定問題的特定要求選擇要使用的正確JOIN。
?例如:查找每個(gè)學(xué)生參加的課程總數(shù)。(提供學(xué)生證、姓名和上課的數(shù)量。)
學(xué)生表和class_history示例表
你可能已經(jīng)注意到,并非所有出現(xiàn)在class_history表中的學(xué)生都出現(xiàn)在學(xué)生表中,這可能是因?yàn)檫@些學(xué)生已不再注冊(cè)。? (這在事務(wù)數(shù)據(jù)庫中實(shí)際上是非常典型的,因?yàn)橛涗浲ǔT诓换顒?dòng)時(shí)會(huì)被刪除。)根據(jù)面試官是否希望結(jié)果中的不活動(dòng)學(xué)生,我們需要使用LEFT JOIN或INNER JOIN來組合兩個(gè)表:
WITH?class_count?AS?(SELECT?student_id,?COUNT(*)?AS?num_of_classFROM?class_historyGROUP?BY?student_id ) SELECTc.student_id,s.student_name,c.num_of_class FROM?class_count?c --?CASE?1:?include?only?active?students JOIN?student?s?ON?c.student_id?=?s.student_id --?CASE?2:?include?all?students --?LEFT?JOIN?student?s?ON?c.student_id?=?s.student_idGROUP BY
?
GROUP BY是SQL中最重要的功能,因?yàn)樗鼜V泛用于數(shù)據(jù)聚合。如果在SQL問題中看到諸如求和、平均值、最小值或最大值之類的關(guān)鍵字,則表明你可能應(yīng)該在查詢中使用GROUP BY。一個(gè)常見的陷阱是在過濾數(shù)據(jù)和GROUP BY時(shí)混合使用WHERE和HAVING,我見過很多人會(huì)犯此錯(cuò)誤。
例如:計(jì)算每個(gè)學(xué)生在每個(gè)學(xué)年中平均所需的課程GPA,并找到每個(gè)學(xué)期符合Dean's List(GPA≥3.5)資格的學(xué)生。
gpa_history示例表
由于我們?cè)贕PA計(jì)算中僅考慮必修課程,因此需要使用WHERE is_required = TRUE排除可選課程。我們需要每位學(xué)生每年的平均GPA,因此我們將按GROUPS的thestudent_id和theschool_year列并取thegpa列的平均值。最后,我們僅保留學(xué)生平均GPA高于3.5的行,可以使用HAVING來實(shí)現(xiàn)。讓我們將所有內(nèi)容放在一起:
SELECTstudent_id,school_year,AVG(gpa)?AS?avg_gpa FROM?gpa_history WHERE?is_required?=?TRUE GROUP?BY?student_id,?school_year HAVING?AVG(gpa)?>=?3.5注意,每當(dāng)在查詢中使用GROUP BY時(shí),你都只能選擇“分組依據(jù)”列和聚合列,因?yàn)槠渌兄械男屑?jí)信息已被舍棄。
有些人可能想知道WHERE和HAVING之間有什么區(qū)別,或者為什么我們不只是寫HAVING avg_gpa> = 3.5而未指定函數(shù)。我將在下一節(jié)中詳細(xì)解釋。
?
SQL查詢執(zhí)行順序
?
多數(shù)人從SELECT開始從上到下編寫SQL查詢,但是你知道SELECT是SQL引擎執(zhí)行的最后一個(gè)函數(shù)之一嗎?以下是SQL查詢的執(zhí)行順序:
FROM, JOIN
WHERE
GROUP BY
HAVING
SELECT
DISTINCT
ORDER BY
LIMIT, OFFSET
再次考慮前面的示例。因?yàn)槲覀兿朐谟?jì)算平均GPA之前過濾掉可選課程,所以我使用WHERE is_required = TRUE代替HAVING,因?yàn)閃HERE在GROUP BY和HAVING之前執(zhí)行。我無法寫HAVING avg_gpa> = 3.5的原因是,avg_gpa被定義為SELECT的一部分,因此無法在SELECT之前執(zhí)行的步驟中引用它。
我建議在編寫查詢時(shí)遵循執(zhí)行順序,這在你編寫復(fù)雜查詢時(shí)會(huì)很有幫助。
? ? ? ?? ? ? ?
窗口函數(shù)
?
窗口函數(shù)也經(jīng)常出現(xiàn)在SQL面試中。共有五種常見的窗口函數(shù):
RANK / DENSE_RANK / ROW_NUMBER:這些通過排序特定列為每行分配一個(gè)等級(jí)。如果給出了任何分區(qū)列,則行將在其所屬的分區(qū)組中排名。
LAG / LEAD:它根據(jù)指定的順序和分區(qū)組從前一行或后一行檢索列值。
在SQL面試中,了解排名函數(shù)之間的區(qū)別以及知道何時(shí)使用LAG / LEAD至關(guān)重要。?
例如:查找每個(gè)部門中薪水最高的前3名員工。
另一個(gè)employee_salary示例表
當(dāng)一個(gè)SQL問題要求輸入“ TOP N”時(shí),我們可以使用ORDER BY或等級(jí)函數(shù)來回答該問題。但是,在此示例中,它要求計(jì)算“每個(gè)Y中的TOP N X”,這強(qiáng)烈暗示我們應(yīng)該使用排名函數(shù),因?yàn)槲覀冃枰獙?duì)每個(gè)分區(qū)組中的行進(jìn)行排名。
以下查詢恰好找到3個(gè)薪水最高的員工,而不論他們的關(guān)系如何:
WITH?T?AS?( SELECT*,ROW_NUMBER()?OVER?(PARTITION?BY?department_id?ORDER?BY?employee_salary?DESC)?AS?rank_in_dep FROM?employee_salary) SELECT?*?FROM?T WHERE?rank_in_dep?<=?3 --?Note:?When?using?ROW_NUMBER,?each?row?will?have?a?unique?rank?number?and?ranks?for?tied?records?are?assigned?randomly.?For?exmaple,?Rimsha?and?Tiah?may?be?rank?2?or?3?in?different?query?runs.此外,根據(jù)應(yīng)如何處理關(guān)系,我們可以選擇其他排名函數(shù)。同樣,細(xì)節(jié)很重要!
ROW_NUMBER,RANK和DENSE_RANK函數(shù)的結(jié)果比較
重復(fù)項(xiàng)
?
SQL面試中的另一個(gè)常見陷阱是忽略數(shù)據(jù)重復(fù)。盡管樣本數(shù)據(jù)中的某些列似乎具有不同的值,但還是希望面試者考慮所有可能性,就像他們?cè)谔幚碚鎸?shí)數(shù)據(jù)集一樣。例如,在上一個(gè)示例的employee_salary表中,可以讓雇員共享相同的名稱。
避免重復(fù)引起的潛在問題的一種簡(jiǎn)單方法是始終使用ID列唯一地標(biāo)識(shí)不同的記錄。
例如:使用employee_salary表查找每個(gè)部門的所有部門的總薪水。
正確的解決方案是GROUP BY employee_id,然后使用SUM(employee_salary)計(jì)算總工資。如果需要雇員姓名,請(qǐng)?jiān)谀┪才c雇員表聯(lián)接以檢索雇員姓名信息。
錯(cuò)誤的方法是使用GROUP BY employee_name。
?
NULL
在SQL中,任何謂詞都可以產(chǎn)生三個(gè)值之一:true,false和NULL,這是用于未知或缺失數(shù)據(jù)值的保留關(guān)鍵字。處理NULL數(shù)據(jù)集可能會(huì)出乎意料的棘手。在SQL面試中,面試官可能會(huì)特別注意你的解決方案是否處理了NULL值。有時(shí)很明顯,如果一列不可為空(例如ID列),但是對(duì)于大多數(shù)其他列,很有可能會(huì)有NULL值。
我建議確認(rèn)示例數(shù)據(jù)中的鍵列是否可為空,如果可以,請(qǐng)利用IS(NOT)NULL,IFNULL和COALESCE之類的功能來覆蓋這些極端情況。
交流
?
最后一條但也很重要的一點(diǎn)是:在SQL面試期間保持交流。?
我面試了許多面試者,他們幾乎沒有說話,除非他們有疑問,如果他們最終提出了完美的解決方案,那就沒問題了。但是,在技術(shù)面試過程中保持交流通常是一個(gè)方法。例如,你可以談?wù)撃銓?duì)問題和數(shù)據(jù)的理解,計(jì)劃如何解決問題,為什么使用某些功能而不是其他替代方法以及正在考慮哪些極端情況。
如果有不清楚的地方或其他意見,歡迎評(píng)論告訴我們。
?歸類成幾個(gè)重點(diǎn)就是:
保持主動(dòng)提問,以保證可以先了解所需要知道的細(xì)節(jié)
在INNER,LEFT和FULL JOIN之間進(jìn)行仔細(xì)選擇。
使用GROUP BY聚合數(shù)據(jù)并正確使用WHERE和HAVING。
了解這三個(gè)排名功能之間的差異。
知道何時(shí)使用LAG / LEAD窗口功能。
如果您在創(chuàng)建復(fù)雜的查詢時(shí)遇到困難,請(qǐng)嘗試遵循SQL執(zhí)行順序。
考慮潛在的數(shù)據(jù)問題,例如重復(fù)和NULL值。
與面試官溝通您的思維過程。
為了幫助您了解如何在實(shí)際的SQL采訪中使用這些策略,我將在下面的視頻中從頭到尾逐步介紹一個(gè)示例SQL采訪問題:
視頻連接:https://youtu.be/EjETvPfiwYw
原文:https://towardsdatascience.com/crack-sql-interviews-6a5fc90ec763
推薦閱讀:還不知道 AWS 是什么?這 11 個(gè)重點(diǎn)帶你認(rèn)識(shí) AWS ! 數(shù)據(jù)庫連接池的原理沒你想得這么復(fù)雜 為什么程序員如此“嫌棄”主干開發(fā)模式? 智能合約編寫之 Solidity 的設(shè)計(jì)模式 2020年,5種將死的編程語言 我去,同事居然用明文存儲(chǔ)密碼!!! 真香,朕在看了!總結(jié)
以上是生活随笔為你收集整理的破解面试难题8个角度带你解读SQL面试技巧!的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2020年进军 AI,想年薪 40 万,
- 下一篇: 数据库中间件漫谈——看看云时代,它会走向