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

▊《對比Excel,輕松學(xué)習(xí)SQL數(shù)據(jù)分析》
張俊紅 著
學(xué)習(xí)SQL 的主要原因是工作需要。網(wǎng)上關(guān)于數(shù)據(jù)相關(guān)崗位的招聘都要求有熟練使用SQL 這一條,為什么會這樣呢?這是因為我們負(fù)責(zé)的是與數(shù)據(jù)相關(guān)的工作,而獲取數(shù)據(jù)是我們工作的第一步,比如,你要通過數(shù)據(jù)做決策,但是現(xiàn)在公司的數(shù)據(jù)基本上不存儲在本地Excel 表中,而是存儲在數(shù)據(jù)庫中,想要從數(shù)據(jù)庫中獲取數(shù)據(jù)就需要使用SQL,所以熟練使用SQL 成了數(shù)據(jù)相關(guān)從業(yè)者入職的必要條件。本書的所有代碼和函數(shù)均以MySQL 8.0 為主。
(掃碼了解本書詳情)
如果喜歡本文
歡迎 在看丨留言丨分享至朋友圈 三連
熱文推薦
▼點擊閱讀原文,獲取本書詳情~
