【面試題】
有一張“電話費用表”,包含3個字段:電話號碼(8位數)、月份、月消費。
其中,月消費爲0表明該月沒有產生費用。
第一行數據含義:64262631的號碼在2017年11月份產生了30.6元的話費。
問題:查找2017年6、7、8月有話費,但是9、10月沒有產生話費,並且6、7、8月話費均在51-100元之間的電話號碼。
【解題步驟】
1. 彙總分析
首先,通過簡單查詢獲取滿足6、7、8月三個月份條件的電話號碼:
1)條件一:2017年6、7、8月有話費;
2)條件二:6、7、8月話費均在51-100元之間。
如果直接用簡單查詢,就無法使得6、7、8月同時滿足以上條件。所以,這裏面要用到分組彙總查詢。
先按電話號碼分組(group by 電話號碼),得到每個電話號碼月話費的最小值(min)、最大值(max)。
然後對分組後的結果用having子句篩選出符合條件的數據,也就是選出3個月(having count(distinct 月份) = 3)話費均在51-100元之間(min(月消費) >= 51 and max(月消費) <= 100)
運行SQL語句,獲得查詢結果(中間結果一):
其次,獲取9、10月的話費記錄:
運行SQL語句,獲得查詢結果(中間結果二):
“中間結果二”中只有一條話費記錄,滿足“9、10月沒有產生話費”條件的號碼只有這一個嗎?
不是。還有一種情況,那就是在“電話費用表”中沒有的電話號碼,說明也沒有產生話費。
2. 多表聯結
爲了滿足“9、10月沒有產生話費”的條件,這裏面有兩種情況:
1)在“電話費用表”中沒有9、10月的話費記錄;
2)在“電話費用表”中有9、10月的話費記錄,但是月消費爲0。
將步驟1中的“中間結果一”與“中間結果二”聯結:
爲了保留在“電話費用表”中沒有9、10月話費記錄的電話號碼,就得保留左表中的全部數據。所以選擇左聯結。
運行SQ語句,獲得結果:
我們發現“中間結果二”就是最終結果,原因是:
1)64262701號碼在“電話費用表”中沒有9、10月的話費記錄,說明沒有產生話費;
2)64262715號碼在“電話費用表”中10月消費爲0,說明也沒有產生話費。
【本題考點】
1)考查對分組彙總的瞭解,以及靈活使用來解決業務問題;
2)考查對多表聯結語句的熟練程度;
3)考查對常見函數的使用:count()、min()、max()。
【舉一反三】
問題:查詢所有4、5月份月均使用金額在30元以上的電話號碼(結果不能重複出現)。
還是考察的對分組彙總的靈活使用。
思考:求4、5月份的月均使用金額爲何不直接用avg() 函數?