破解面试难题8个角度带你解读SQL面试技巧!
作者 |?Xinran Waibel
譯者 | 天道酬勤?責編 | 徐威龍
封圖|?CSDN 下載于視覺中國
SQL是用于數(shù)據(jù)分析和數(shù)據(jù)處理的最重要的編程語言之一,因此SQL問題始終是與數(shù)據(jù)科學相關(guān)工作(例如數(shù)據(jù)分析師、數(shù)據(jù)科學家和數(shù)據(jù)工程師)面試過程中的一部分。? SQL面試旨在評估應(yīng)聘者的技術(shù)和解決問題的能力。因此,至關(guān)重要的是,不僅要根據(jù)樣本數(shù)據(jù)編寫正確的查詢語句,而且還要像對待現(xiàn)實數(shù)據(jù)集一樣考慮各種情況和極端情況。
作者曾幫助設(shè)計和執(zhí)行針對數(shù)據(jù)科學面試者的SQL面試問題,并親自為大型技術(shù)公司和初創(chuàng)公司進行了許多SQL面試。在這篇文章中,作者將解釋SQL面試問題中常見的模式,并提供有關(guān)如何在SQL查詢中巧妙處理它們的技巧。
?
詢問問題
?
要搞定SQL面試,最重要的是通過詢問所需的盡可能多的問題來確保擁有給定任務(wù)和數(shù)據(jù)樣本的所有詳細信息。理解需求可以節(jié)省你以后迭代問題的時間,并使你能夠很好地處理極端情況。?
我注意到許多面試候選者往往不了解SQL問題或數(shù)據(jù)集就直接進入解決方案。后來,在我指出解決方案中的問題之后,他們不得不重復(fù)修改查詢。最后,他們在迭代中浪費了很多面試時間,甚至可能還沒有找到正確的解決方案。
我建議將SQL面試視作你正在與業(yè)務(wù)合作伙伴一起工作。在提供解決方案之前,你希望收集對數(shù)據(jù)請求的所有要求。
例如:查找薪水最高的前3名員工。? ? ??
?
employee_salary示例表
你應(yīng)要求面試官解釋清楚“前三名”的含義。我應(yīng)該在結(jié)果中包括3名員工嗎?你要我如何處理關(guān)系?此外,請仔細查看樣本員工數(shù)據(jù)。薪水字段的數(shù)據(jù)類型是什么?在計算之前是否需要清除數(shù)據(jù)?
?
哪個JOIN?
? ? ? ? ? ? ?
資料來源:MindMajix
在SQL中,JOIN通常用于合并來自多個表的信息。有四種不同類型的JOIN,但是在大多數(shù)情況下,我們僅使用INNER、LEFT和FULL JOIN,因為RIGHT JOIN不是很直觀,可以使用LEFT JOIN輕松地重寫。在SQL面試中,你需要根據(jù)給定問題的特定要求選擇要使用的正確JOIN。
?例如:查找每個學生參加的課程總數(shù)。(提供學生證、姓名和上課的數(shù)量。)
學生表和class_history示例表
你可能已經(jīng)注意到,并非所有出現(xiàn)在class_history表中的學生都出現(xiàn)在學生表中,這可能是因為這些學生已不再注冊。? (這在事務(wù)數(shù)據(jù)庫中實際上是非常典型的,因為記錄通常在不活動時會被刪除。)根據(jù)面試官是否希望結(jié)果中的不活動學生,我們需要使用LEFT JOIN或INNER JOIN來組合兩個表:
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中最重要的功能,因為它廣泛用于數(shù)據(jù)聚合。如果在SQL問題中看到諸如求和、平均值、最小值或最大值之類的關(guān)鍵字,則表明你可能應(yīng)該在查詢中使用GROUP BY。一個常見的陷阱是在過濾數(shù)據(jù)和GROUP BY時混合使用WHERE和HAVING,我見過很多人會犯此錯誤。
例如:計算每個學生在每個學年中平均所需的課程GPA,并找到每個學期符合Dean's List(GPA≥3.5)資格的學生。
gpa_history示例表
由于我們在GPA計算中僅考慮必修課程,因此需要使用WHERE is_required = TRUE排除可選課程。我們需要每位學生每年的平均GPA,因此我們將按GROUPS的thestudent_id和theschool_year列并取thegpa列的平均值。最后,我們僅保留學生平均GPA高于3.5的行,可以使用HAVING來實現(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注意,每當在查詢中使用GROUP BY時,你都只能選擇“分組依據(jù)”列和聚合列,因為其他列中的行級信息已被舍棄。
有些人可能想知道WHERE和HAVING之間有什么區(qū)別,或者為什么我們不只是寫HAVING avg_gpa> = 3.5而未指定函數(shù)。我將在下一節(jié)中詳細解釋。
?
SQL查詢執(zhí)行順序
?
多數(shù)人從SELECT開始從上到下編寫SQL查詢,但是你知道SELECT是SQL引擎執(zhí)行的最后一個函數(shù)之一嗎?以下是SQL查詢的執(zhí)行順序:
FROM, JOIN
WHERE
GROUP BY
HAVING
SELECT
DISTINCT
ORDER BY
LIMIT, OFFSET
再次考慮前面的示例。因為我們想在計算平均GPA之前過濾掉可選課程,所以我使用WHERE is_required = TRUE代替HAVING,因為WHERE在GROUP BY和HAVING之前執(zhí)行。我無法寫HAVING avg_gpa> = 3.5的原因是,avg_gpa被定義為SELECT的一部分,因此無法在SELECT之前執(zhí)行的步驟中引用它。
我建議在編寫查詢時遵循執(zhí)行順序,這在你編寫復(fù)雜查詢時會很有幫助。
? ? ? ?? ? ? ?
窗口函數(shù)
?
窗口函數(shù)也經(jīng)常出現(xiàn)在SQL面試中。共有五種常見的窗口函數(shù):
RANK / DENSE_RANK / ROW_NUMBER:這些通過排序特定列為每行分配一個等級。如果給出了任何分區(qū)列,則行將在其所屬的分區(qū)組中排名。
LAG / LEAD:它根據(jù)指定的順序和分區(qū)組從前一行或后一行檢索列值。
在SQL面試中,了解排名函數(shù)之間的區(qū)別以及知道何時使用LAG / LEAD至關(guān)重要。?
例如:查找每個部門中薪水最高的前3名員工。
另一個employee_salary示例表
當一個SQL問題要求輸入“ TOP N”時,我們可以使用ORDER BY或等級函數(shù)來回答該問題。但是,在此示例中,它要求計算“每個Y中的TOP N X”,這強烈暗示我們應(yīng)該使用排名函數(shù),因為我們需要對每個分區(qū)組中的行進行排名。
以下查詢恰好找到3個薪水最高的員工,而不論他們的關(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ù)。同樣,細節(jié)很重要!
ROW_NUMBER,RANK和DENSE_RANK函數(shù)的結(jié)果比較
重復(fù)項
?
SQL面試中的另一個常見陷阱是忽略數(shù)據(jù)重復(fù)。盡管樣本數(shù)據(jù)中的某些列似乎具有不同的值,但還是希望面試者考慮所有可能性,就像他們在處理真實數(shù)據(jù)集一樣。例如,在上一個示例的employee_salary表中,可以讓雇員共享相同的名稱。
避免重復(fù)引起的潛在問題的一種簡單方法是始終使用ID列唯一地標識不同的記錄。
例如:使用employee_salary表查找每個部門的所有部門的總薪水。
正確的解決方案是GROUP BY employee_id,然后使用SUM(employee_salary)計算總工資。如果需要雇員姓名,請在末尾與雇員表聯(lián)接以檢索雇員姓名信息。
錯誤的方法是使用GROUP BY employee_name。
?
NULL
在SQL中,任何謂詞都可以產(chǎn)生三個值之一:true,false和NULL,這是用于未知或缺失數(shù)據(jù)值的保留關(guān)鍵字。處理NULL數(shù)據(jù)集可能會出乎意料的棘手。在SQL面試中,面試官可能會特別注意你的解決方案是否處理了NULL值。有時很明顯,如果一列不可為空(例如ID列),但是對于大多數(shù)其他列,很有可能會有NULL值。
我建議確認示例數(shù)據(jù)中的鍵列是否可為空,如果可以,請利用IS(NOT)NULL,IFNULL和COALESCE之類的功能來覆蓋這些極端情況。
交流
?
最后一條但也很重要的一點是:在SQL面試期間保持交流。?
我面試了許多面試者,他們幾乎沒有說話,除非他們有疑問,如果他們最終提出了完美的解決方案,那就沒問題了。但是,在技術(shù)面試過程中保持交流通常是一個方法。例如,你可以談?wù)撃銓栴}和數(shù)據(jù)的理解,計劃如何解決問題,為什么使用某些功能而不是其他替代方法以及正在考慮哪些極端情況。
如果有不清楚的地方或其他意見,歡迎評論告訴我們。
?歸類成幾個重點就是:
保持主動提問,以保證可以先了解所需要知道的細節(jié)
在INNER,LEFT和FULL JOIN之間進行仔細選擇。
使用GROUP BY聚合數(shù)據(jù)并正確使用WHERE和HAVING。
了解這三個排名功能之間的差異。
知道何時使用LAG / LEAD窗口功能。
如果您在創(chuàng)建復(fù)雜的查詢時遇到困難,請嘗試遵循SQL執(zhí)行順序。
考慮潛在的數(shù)據(jù)問題,例如重復(fù)和NULL值。
與面試官溝通您的思維過程。
為了幫助您了解如何在實際的SQL采訪中使用這些策略,我將在下面的視頻中從頭到尾逐步介紹一個示例SQL采訪問題:
視頻連接:https://youtu.be/EjETvPfiwYw
原文:https://towardsdatascience.com/crack-sql-interviews-6a5fc90ec763
推薦閱讀:還不知道 AWS 是什么?這 11 個重點帶你認識 AWS ! 數(shù)據(jù)庫連接池的原理沒你想得這么復(fù)雜 為什么程序員如此“嫌棄”主干開發(fā)模式? 智能合約編寫之 Solidity 的設(shè)計模式 2020年,5種將死的編程語言 我去,同事居然用明文存儲密碼!!! 真香,朕在看了!總結(jié)
以上是生活随笔為你收集整理的破解面试难题8个角度带你解读SQL面试技巧!的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2020年进军 AI,想年薪 40 万,
- 下一篇: 【IPF2020】浪潮集团副总裁、渠道管