【抖音面試題】
有一張“用戶登陸記錄表”,包含兩個字段:用戶id、日期。
【問題】查詢2021年每個月,連續2天都有登陸的用戶名單。
【解題步驟】
1.思路
怎麼能知道連續登陸用戶呢?
首先對用戶連續登陸進行標記,也就是日期相同的打賞同一個標記(如下圖)。
然後,用登陸日期的“天”和“每個月登陸順序”的差值來做標記(如下圖)。這樣就可以知道,當登陸日期連續時,差值就是相同的,代表這些天用戶是連續登陸。
根據上圖的標記,怎麼查詢出每個用戶每個月連續登陸的天數呢?
可以用分組彙總,也就是分組(group by 月,用戶id),統計(對分組後每個組計數就是連續登陸的天數 count)
2. 子查詢
1)獲取登陸日期的天,需要用到day()函數;
2)獲取登錄日期的月,需要用到month()函數;
3)獲取每個月登陸順序,這類問題屬於“每個+排序”,要想到用《猴子 從零學會SQL》裏講過的知識,用到窗口函數row_number();
4)篩選出2021年的數據。
把上面內容寫成SQL就是:
查詢結果(把這個SQL記爲子查詢t1):
用“天”和“每個月登陸順序”的差值來做標記,也就是上面我們說過的這個圖:
查詢結果(把這個SQL記爲子查詢t2):
3. 彙總分析
1)分組彙總:查詢每個月,每個用戶,每一次連續登陸的天數。
也就是分組(group by 月,用戶id,標記),統計(對分組後每個組計數就是連續登陸的天數 count)
查詢結果(把這個SQL記爲子查詢t3):
2)在上一步的基礎上,用where子句篩選出連續2天都有登陸的用戶:
到這裏我們已經得到了題目要求的結果,可以把前面的子查詢t1、t2、t3代入上面的SQL語句,就得到了最終的SQL:
查詢結果:
【本題考點】
1.考查對複雜問題的拆解能力,可以使用邏輯樹分析方法,將一個複雜問題拆解爲可以解決的子問題,然後逐步解決
2.對子查詢的應用,當一個複雜問題需要多個子問題來解決時候,可以把每個子問題寫成一個子查詢
3.考查對常見函數的瞭解:month()、day()、count();
4.考查對窗口函數的應用,窗口函數能解決的幾類典型問題要能牢記;
【舉一反三】
查詢2021年每個月,連續5天都有登陸的用戶數。
與原題的區別在於:
1)“連續2天”變成了“連續5天”:對最後的where條件進行修改;
2)查詢“用戶名單”變成了“用戶數”:用group by按月分組,然後統計用戶數和count(distinct 用戶id)。