本篇節選自書籍《對比Excel,輕鬆學習SQL數據分析》一書,主要講解數據分析面試中常見的30道SQL面試題。
現在有一張全校學生信息表stu_table,這張表存儲了每位學生的id、name(姓名)、class(班級)、sex(性別)以及一些其他信息,現在我們想知道每個班有多少學生,該怎麼實現呢?
stu_table表如下所示:
idnameclasssex4張文華二班男3李思雨一班女1王小鳳一班女7李智瑞三班男6徐文杰二班男8徐雨秋三班男5張青雲二班女9孫皓然三班男10李春山三班男2劉詩迪一班女自己先想一下代碼怎麼寫,然後再參考我的代碼。
select
class
,count(id) as stu_num
from
demo.stu_table
group by
class解題思路:
我們是要獲取每個班的學生數,首先需要對班級進行分組,使用的是group by;然後再對每個組內的學生進行計數聚合運算,使用的count。最後運行結果如下:
2 查詢每個班男女學生數還是前面的全校學生信息表stu_table,現在我們想知道每個班男生女生分別有多少個?
自己先想一下代碼怎麼寫,然後再參考我的代碼。
select
class
,sex
,count(id) as stu_num
from
demo.stu_table
group by
class
,sex解題思路:
與第一題不同的是,不僅需要每個班級的信息,還需要每個班級裡面男女生分別的信息,主要考察的就是按照多列分組聚合的知識,直接在group by後面指明要分組的多列即可,且列與列之間用逗號分隔開。最後運行結果如下:
classsexstu_num二班男2一班女3三班男4二班女13 姓張的同學有多少個還是前面的全校學生信息表stu_table,現在我們想知道這張表中姓張的同學有多少個?
自己先想一下代碼怎麼寫,然後再參考我的代碼。
select
count(id) as stu_num
from
demo.stu_table
where name like "張%"解題思路:
我們是要獲取姓張的同學有多少個,首先需要思考的是怎麼去判斷同學是否姓張,假設我們表裡面存儲的姓名都是先姓後名的形式,那就可以用到字符串匹配函數like;知道怎麼判斷同學是否姓張,接下來就是把這些同學篩選出來,使用的是where條件;最後針對篩選出來的同學進行計數,使用的是count。最後運行結果如下:
4 篩選出id第3-5的同學還是前面的全校學生信息表stu_table,現在我們要獲取id從小到大排序以後第3-5位的同學的信息。
自己先想一下代碼怎麼寫,然後再參考我的代碼。
select
*
from
demo.stu_table
order by id asc
limit 2,3解題思路:
我們要獲取id從小到大排序以後第3-5位的同學,因為不確定id是否連續,所以我們沒法直接用where條件來篩選id。我們先對id進行升序排列,然後再利用limit進行篩選。最後運行結果如下:
idnameclasssex3李思雨一班女4張文華二班男5張青雲二班女5 篩選出掛科的同學現在有一張學生成績表score_table,這張表存儲了每位學生的id、name(姓名)、class(班級)、score(成績),現在我們想要把掛科(成績小於60)的同學信息篩選出來。
score_table表如下所示:
idnameclassscore1王小鳳一班882劉詩迪一班703李思雨一班924張文華二班555張青雲二班776徐文杰二班777李智瑞三班568徐雨秋三班919孫皓然三班9310李春山三班57自己先想一下代碼怎麼寫,然後再參考我的代碼。
select
*
from
demo.score_table
where score < 60解題思路:
我們要獲取掛科同學的信息,只需要加一個where條件用來限定掛科這個條件即可。最後運行結果如下:
idnameclassscore4張文華二班557李智瑞三班5610李春山三班576 篩選姓張的且掛科的同學我們現在需要根據學生成績表score_table查找出姓張的且掛科的同學的信息。
自己先想一下代碼怎麼寫,然後再參考我的代碼。
select
*
from
demo.score_table
where score < 60
and name like "張%"解題思路:
這裡面主要是用到了多條件篩選,多個條件之間用and進行關聯即可。最後運行結果如下:
7 查詢銷冠獲得次數我們有一張表month_table記錄了每月的銷售冠軍信息,這張表存儲了每月銷冠的id、name(姓名)、month_num(月份),現在需要獲取銷冠次數超過2次的人以及其對應的做銷冠次數。
month_table表如下所示:
idnamemonth_numE002王小鳳1E001張文華2E003孫皓然3E001張文華4E002王小鳳5E001張文華6E004李智瑞7E002王小鳳8E003孫皓然9自己先想一下代碼怎麼寫,然後再參考我的代碼。
select
id
,name
,count(month_num) num
from
demo.month_table
group by
id
,name
having
count(month_num) > 2解題思路:
我們要獲取銷冠次數超過2次的人以及其對應的做銷冠次數,首先需要獲取每個人做銷冠的次數,對id進行group by,然後在組內對month_num進行計數即可;然後再對分組聚合後的結果利用having進行條件篩選。最後結果如下:
idnamenumE002王小鳳3E001張文華38 獲取每個部門一整年業績提升幅度現在有一個月份銷售額記錄表sale_table,這個表記錄了每年每月的銷售額,現在我們想看下今年(2019年),月銷售額最高漲幅是多少?
sale_table表如下所示:
year_nummonth_numsales201912854201924772201933542201941336201953544201812293201822559201832597201842363自己先想一下代碼怎麼寫,然後再參考我的代碼。
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條件把今年的每月數據銷售額篩選出來;然後再在今年的月銷售額裡面尋找最大和最小的銷售額,對兩者進行做差,就是我們想要的結果。最後運行結果如下:
max_salesmin_saleschagrowth4772133634362.57199 查找每科成績大於70的學生我們有一張學生科目成績表score_info_table,這張表記錄了每一位同學每一科目的成績,每一位同學的每科成績是一行,現在我們想要通過這張表獲取到每科成績都大於70分的學生。
score_info_table表如下所示:
idnamesubjectscore1王小鳳語文882張文華數學703徐雨秋英語921王小鳳語文552張文華數學773徐雨秋英語771王小鳳語文722張文華數學913徐雨秋英語93自己先想一下代碼怎麼寫,然後再參考我的代碼。
select
id
,name
from
demo.score_info_table
group by
id
,name
having
min(score) > 70解題思路:
我們是要獲取每科成績大於70的學生,只要能夠保證最小成績是大於70分的,就說明這位同學每科成績都大於70分.所以第一步就是先獲取每位同學的最小成績,先對name進行group by分組,再在組內求最小值,然後將最小成績大於70分的同學通過having篩選出來即可。最後運行結果如下:
10 刪除重複值現在有一個學生信息表stu_info_table,這張表存儲了每位學生id、name(姓名)、class(班級)、grade(年級),現在我們想獲取這個學校所有年級以及所有班級的信息,即哪些年級有哪些班級,該怎麼獲取?
stu_info_table表如下所示:
idnameclassgrade1王小鳳一班一年級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列是主鍵,即不重複的,但是class和grade是重複的,多個id會屬於同一個class和grade。我們只要class和grade信息,所以是需要對這兩列進行去重,去重我們除了用distinct以外,還可以用group by。最後運行結果如下:
gradeclass一年級一班一年級二班二年級一班二年級二班想進一步了解更多內容的同學,可以點擊下方連結: