30道经典SQL面试题讲解(1-10)
本篇節(jié)選自書籍《對比Excel,輕松學(xué)習(xí)SQL數(shù)據(jù)分析》一書,主要講解數(shù)據(jù)分析面試中常見的30道SQL面試題。
1 查詢每個班學(xué)生數(shù)
現(xiàn)在有一張全校學(xué)生信息表stu_table,這張表存儲了每位學(xué)生的id、name(姓名)、class(班級)、sex(性別)以及一些其他信息,現(xiàn)在我們想知道每個班有多少學(xué)生,該怎么實(shí)現(xiàn)呢?
stu_table表如下所示:
| 4 | 張文華 | 二班 | 男 |
| 3 | 李思雨 | 一班 | 女 |
| 1 | 王小鳳 | 一班 | 女 |
| 7 | 李智瑞 | 三班 | 男 |
| 6 | 徐文杰 | 二班 | 男 |
| 8 | 徐雨秋 | 三班 | 男 |
| 5 | 張青云 | 二班 | 女 |
| 9 | 孫皓然 | 三班 | 男 |
| 10 | 李春山 | 三班 | 男 |
| 2 | 劉詩迪 | 一班 | 女 |
自己先想一下代碼怎么寫,然后再參考我的代碼。
select?class,count(id)?as?stu_num fromdemo.stu_table group?byclass解題思路:
我們是要獲取每個班的學(xué)生數(shù),首先需要對班級進(jìn)行分組,使用的是group by;然后再對每個組內(nèi)的學(xué)生進(jìn)行計(jì)數(shù)聚合運(yùn)算,使用的count。最后運(yùn)行結(jié)果如下:
| 二班 | 3 |
| 一班 | 3 |
| 三班 | 4 |
2 查詢每個班男女學(xué)生數(shù)
還是前面的全校學(xué)生信息表stu_table,現(xiàn)在我們想知道每個班男生女生分別有多少個?
自己先想一下代碼怎么寫,然后再參考我的代碼。
select?class,sex,count(id)?as?stu_num fromdemo.stu_table group?byclass,sex解題思路:
與第一題不同的是,不僅需要每個班級的信息,還需要每個班級里面男女生分別的信息,主要考察的就是按照多列分組聚合的知識,直接在group by后面指明要分組的多列即可,且列與列之間用逗號分隔開。最后運(yùn)行結(jié)果如下:
| 二班 | 男 | 2 |
| 一班 | 女 | 3 |
| 三班 | 男 | 4 |
| 二班 | 女 | 1 |
3 姓張的同學(xué)有多少個
還是前面的全校學(xué)生信息表stu_table,現(xiàn)在我們想知道這張表中姓張的同學(xué)有多少個?
自己先想一下代碼怎么寫,然后再參考我的代碼。
select?count(id)?as?stu_num fromdemo.stu_table where?name?like?"張%"解題思路:
我們是要獲取姓張的同學(xué)有多少個,首先需要思考的是怎么去判斷同學(xué)是否姓張,假設(shè)我們表里面存儲的姓名都是先姓后名的形式,那就可以用到字符串匹配函數(shù)like;知道怎么判斷同學(xué)是否姓張,接下來就是把這些同學(xué)篩選出來,使用的是where條件;最后針對篩選出來的同學(xué)進(jìn)行計(jì)數(shù),使用的是count。最后運(yùn)行結(jié)果如下:
| 2 |
4 篩選出id第3-5的同學(xué)
還是前面的全校學(xué)生信息表stu_table,現(xiàn)在我們要獲取id從小到大排序以后第3-5位的同學(xué)的信息。
自己先想一下代碼怎么寫,然后再參考我的代碼。
select?* fromdemo.stu_table order?by?id?asc limit?2,3解題思路:
我們要獲取id從小到大排序以后第3-5位的同學(xué),因?yàn)椴淮_定id是否連續(xù),所以我們沒法直接用where條件來篩選id。我們先對id進(jìn)行升序排列,然后再利用limit進(jìn)行篩選。最后運(yùn)行結(jié)果如下:
| 3 | 李思雨 | 一班 | 女 |
| 4 | 張文華 | 二班 | 男 |
| 5 | 張青云 | 二班 | 女 |
5 篩選出掛科的同學(xué)
現(xiàn)在有一張學(xué)生成績表score_table,這張表存儲了每位學(xué)生的id、name(姓名)、class(班級)、score(成績),現(xiàn)在我們想要把掛科(成績小于60)的同學(xué)信息篩選出來。
score_table表如下所示:
| 1 | 王小鳳 | 一班 | 88 |
| 2 | 劉詩迪 | 一班 | 70 |
| 3 | 李思雨 | 一班 | 92 |
| 4 | 張文華 | 二班 | 55 |
| 5 | 張青云 | 二班 | 77 |
| 6 | 徐文杰 | 二班 | 77 |
| 7 | 李智瑞 | 三班 | 56 |
| 8 | 徐雨秋 | 三班 | 91 |
| 9 | 孫皓然 | 三班 | 93 |
| 10 | 李春山 | 三班 | 57 |
自己先想一下代碼怎么寫,然后再參考我的代碼。
select?* fromdemo.score_table where?score?<?60解題思路:
我們要獲取掛科同學(xué)的信息,只需要加一個where條件用來限定掛科這個條件即可。最后運(yùn)行結(jié)果如下:
| 4 | 張文華 | 二班 | 55 |
| 7 | 李智瑞 | 三班 | 56 |
| 10 | 李春山 | 三班 | 57 |
6 篩選姓張的且掛科的同學(xué)
我們現(xiàn)在需要根據(jù)學(xué)生成績表score_table查找出姓張的且掛科的同學(xué)的信息。
自己先想一下代碼怎么寫,然后再參考我的代碼。
select?* fromdemo.score_table where?score?<?60and?name?like?"張%"解題思路:
這里面主要是用到了多條件篩選,多個條件之間用and進(jìn)行關(guān)聯(lián)即可。最后運(yùn)行結(jié)果如下:
| 4 | 張文華 | 二班 | 55 |
7 查詢銷冠獲得次數(shù)
我們有一張表month_table記錄了每月的銷售冠軍信息,這張表存儲了每月銷冠的id、name(姓名)、month_num(月份),現(xiàn)在需要獲取銷冠次數(shù)超過2次的人以及其對應(yīng)的做銷冠次數(shù)。
month_table表如下所示:
| E002 | 王小鳳 | 1 |
| E001 | 張文華 | 2 |
| E003 | 孫皓然 | 3 |
| E001 | 張文華 | 4 |
| E002 | 王小鳳 | 5 |
| E001 | 張文華 | 6 |
| E004 | 李智瑞 | 7 |
| E002 | 王小鳳 | 8 |
| E003 | 孫皓然 | 9 |
自己先想一下代碼怎么寫,然后再參考我的代碼。
select?id,name,count(month_num)?num from?demo.month_table group?by?id,name having?count(month_num)?>?2解題思路:
我們要獲取銷冠次數(shù)超過2次的人以及其對應(yīng)的做銷冠次數(shù),首先需要獲取每個人做銷冠的次數(shù),對id進(jìn)行g(shù)roup by,然后在組內(nèi)對month_num進(jìn)行計(jì)數(shù)即可;然后再對分組聚合后的結(jié)果利用having進(jìn)行條件篩選。最后結(jié)果如下:
| E002 | 王小鳳 | 3 |
| E001 | 張文華 | 3 |
8 獲取每個部門一整年業(yè)績提升幅度
現(xiàn)在有一個月份銷售額記錄表sale_table,這個表記錄了每年每月的銷售額,現(xiàn)在我們想看下今年(2019年),月銷售額最高漲幅是多少?
sale_table表如下所示:
| 2019 | 1 | 2854 |
| 2019 | 2 | 4772 |
| 2019 | 3 | 3542 |
| 2019 | 4 | 1336 |
| 2019 | 5 | 3544 |
| 2018 | 1 | 2293 |
| 2018 | 2 | 2559 |
| 2018 | 3 | 2597 |
| 2018 | 4 | 2363 |
自己先想一下代碼怎么寫,然后再參考我的代碼。
select?max(sales)?as?max_sales,min(sales)?as?min_sales,max(sales)-min(sales)?as?cha,(max(sales)-min(sales))/min(sales)?as?growth from?demo.sale_table where?year_num?=?2019解題思路:
我們要獲取今年的最大月漲幅,首先需要通過where條件把今年的每月數(shù)據(jù)銷售額篩選出來;然后再在今年的月銷售額里面尋找最大和最小的銷售額,對兩者進(jìn)行做差,就是我們想要的結(jié)果。最后運(yùn)行結(jié)果如下:
| 4772 | 1336 | 3436 | 2.5719 |
9 查找每科成績大于70的學(xué)生
我們有一張學(xué)生科目成績表score_info_table,這張表記錄了每一位同學(xué)每一科目的成績,每一位同學(xué)的每科成績是一行,現(xiàn)在我們想要通過這張表獲取到每科成績都大于70分的學(xué)生。
score_info_table表如下所示:
| 1 | 王小鳳 | 語文 | 88 |
| 2 | 張文華 | 數(shù)學(xué) | 70 |
| 3 | 徐雨秋 | 英語 | 92 |
| 1 | 王小鳳 | 語文 | 55 |
| 2 | 張文華 | 數(shù)學(xué) | 77 |
| 3 | 徐雨秋 | 英語 | 77 |
| 1 | 王小鳳 | 語文 | 72 |
| 2 | 張文華 | 數(shù)學(xué) | 91 |
| 3 | 徐雨秋 | 英語 | 93 |
自己先想一下代碼怎么寫,然后再參考我的代碼。
select?id,namefromdemo.score_info_tablegroup?byid,namehaving?min(score)?>?70????解題思路:
我們是要獲取每科成績大于70的學(xué)生,只要能夠保證最小成績是大于70分的,就說明這位同學(xué)每科成績都大于70分.所以第一步就是先獲取每位同學(xué)的最小成績,先對name進(jìn)行g(shù)roup by分組,再在組內(nèi)求最小值,然后將最小成績大于70分的同學(xué)通過having篩選出來即可。最后運(yùn)行結(jié)果如下:
| 3 | 徐雨秋 |
10 刪除重復(fù)值
現(xiàn)在有一個學(xué)生信息表stu_info_table,這張表存儲了每位學(xué)生id、name(姓名)、class(班級)、grade(年級),現(xiàn)在我們想獲取這個學(xué)校所有年級以及所有班級的信息,即哪些年級有哪些班級,該怎么獲取?
stu_info_table表如下所示:
| 1 | 王小鳳 | 一班 | 一年級 |
| 2 | 劉詩迪 | 一班 | 二年級 |
| 3 | 李思雨 | 一班 | 一年級 |
| 4 | 張文華 | 二班 | 二年級 |
| 5 | 張青云 | 二班 | 一年級 |
| 6 | 徐文杰 | 二班 | 二年級 |
| 7 | 李智瑞 | 一班 | 一年級 |
| 8 | 徐雨秋 | 二班 | 二年級 |
| 9 | 孫皓然 | 一班 | 一年級 |
自己先想一下代碼怎么寫,然后再參考我的代碼。
selectgrade,class fromdemo.stu_info_table group?by?grade,class order?bygrade解題思路:
stu_table表中id列是主鍵,即不重復(fù)的,但是class和grade是重復(fù)的,多個id會屬于同一個class和grade。我們只要class和grade信息,所以是需要對這兩列進(jìn)行去重,去重我們除了用distinct以外,還可以用group by。最后運(yùn)行結(jié)果如下:
| 一年級 | 一班 |
| 一年級 | 二班 |
| 二年級 | 一班 |
| 二年級 | 二班 |
想進(jìn)一步了解更多內(nèi)容的同學(xué),可以點(diǎn)擊下方鏈接:
總結(jié)
以上是生活随笔為你收集整理的30道经典SQL面试题讲解(1-10)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 大主宰怎么获取大须弥魔柱?大主宰大须弥魔
- 下一篇: 魔兽世界怀旧服急救150后怎么提升 急救