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