圖解面試題:經典50題

已知有如下4張表:

學生表:student(學號,學生姓名,出生年月,性別)

成績表:score(學號,課程號,成績)

課程表:course(課程號,課程名稱,教師號)

教師表:teacher(教師號,教師姓名)

1.彙總分析

-查詢學生的總成績並進行排名

/*
【知識點】分組查詢
分析思路
select 查詢結果 [總成績:sum(成績), 學號]
from 從哪張表中查找數據 [成績表score]
where 查詢條件 [沒有]
group by 分組 [學生的總成績:按照每個學生學號進行分組]
order by 排序 [按照總成績進行排序:sum(成績)];
/*
select 學號 ,sum(成績) from score 
group by 學號
order by sum(成績) ;

 -查詢平均成績大於60分的學生的學號和平均成績

/*
【知識點】分組+條件
分析思路
select 查詢結果 [學號, 平均成績: avg(成績)]
from 從哪張表中查找數據 [成績表score]
where 查詢條件 [沒有]
group by 分組 [學號]
having 分組條件 [平均成績大於60分:avg(成績 ) >60]
order by 排序 [沒有];
/*
select 學號 ,avg(成績) from score 
group by 學號  
having avg(成績 ) >60

2.複雜查詢

-查詢各學生的年齡(精確到月份)

/*
【知識點】時間格式轉化
*/
select 學號 ,timestampdiff(month ,出生日期 ,now())/12 
from student ;

 -查詢本月過生日的學生

select * 
from student 
where month (出生日期 ) = month(now())+2;


3.多表查詢

-檢索"0001"課程分數小於60,按分數降序排列的學生信息

思路如圖:

select a.*,b.成績 
from student as a 
inner join score as b 
on a.學號 =b.學號 
where b.成績 <60 and b.課程號 =01
order by b.成績 desc;

 

-查詢不同老師所教不同課程平均分從高到低顯示

【知識點】分組+條件+排序+多表連接,思路如圖

select a.教師號,a.教師姓名,avg(c.成績) 
from  teacher as a 
inner join course as b 
on a.教師號= b.教師號
inner join score  c on b.課程號= c.課程號
group by a.教師姓名
order by avg(c.成績) desc;

-查詢課程名稱爲"數學",且分數低於60的學生姓名和分數

【知識點】多表連接,思路如圖

 

select a.姓名,b.成績 
from student as a 
inner join score as b 
on a.學號 =b.學號 
inner join course c on b.課程號 =c.課程號 
where b.成績  <60 and c.課程名稱 ='數學';

 

-查詢任何一門課程成績在70分以上的姓名、課程名稱和分數(與上題類似)

select a.姓名,c.課程名稱 ,b.成績 
from student as a 
inner join score as b 
on a.學號=b.學號
inner join course c on b.課程號 =c.課程號 
where b.成績 >70;

 

 -查詢兩門及其以上不及格課程的同學的學號,姓名及其平均成績

【知識點】分組+條件+多表連接

翻譯成大白話:計算每個學號不及格分數個數,篩選出大於2個的學號並找出姓名,平均成績,思路如圖:

select b.姓名,avg(a.成績),a.學號  
from score as a
inner join student as b 
on a.學號 =b.學號 
where a.成績 <60
group by a.學號 
having count(a.學號 ) >=2;

 

-查詢不同課程成績相同的學生的學生編號、課程編號、學生成績

select distinct a.學號 ,a.成績 ,a.課程號 
from score as a 
inner join score as b 
on a.學號 =b.學號 
where a.成績 =b.成績 and a.課程號 != b.課程號 ;

-查詢課程編號爲“0001”的課程比“0002”的課程成績高的所有學生的學號

【知識點】多表連接+條件,思路如圖

 

select a.學號  
from 
(select 學號 ,成績 from score where 課程號=01) as a
inner join 
(select 學號 ,成績 from score where 課程號=02) as b
on a.學號 =b.學號 
inner join student c on c.學號 =a.學號 
where a.成績 >b.成績 ;

 

-查詢學過編號爲“0001”的課程並且也學過編號爲“0002”的課程的學生的學號、姓名

思路如圖

select a.學號  
from 
(select 學號 ,成績 from score where 課程號=01) as a
inner join 
(select 學號 ,成績 from score where 課程號=02) as b
on a.學號 =b.學號 
inner join student c on c.學號 =a.學號 
where a.成績 >b.成績 ;

-查詢學過“孟扎扎”老師所教的所有課的同學的學號、姓名

思路如圖

 

select s.學號 ,s.姓名,a.學號 ,b.課程號,c.教師號 ,c.教師姓名
from student as s  
inner join score as a  
on s.學號 =a.學號 
inner join  course  b on a.課程號 =b.課程號
inner join  teacher c  on b.教師號 = c.教師號
where c.教師姓名 ='孟扎扎';

 

-查詢沒學過"孟扎扎"老師講授的任一門課程的學生姓名 與上題類似,"沒學過"用not in來實現)

 

select 姓名 ,學號 
from student 
where 學號 not in (
select a.學號 
from student as a 
inner join score as b
on a.學號 =b.學號 
inner join course as c on b.課程號 =c.課程號 
inner join teacher as d on c.教師號 =d.教師號 
where d.教師姓名 ='孟扎扎');

 

-查詢沒學過“孟扎扎”老師課的學生的學號、姓名(與上題類似)

 

select 學號, 姓名 
from student 
where 學號 not in 
(select 學號 from score where 課程號=
(select 課程號 from course  where 教師號 = 
(select 教師號 from teacher where 教師姓名 ='孟扎扎')
)
);

 -查詢選修“孟扎扎”老師所授課程的學生中成績最高的學生姓名及其成績(與上題類似,用成績排名,用 limit 1得出最高一個)

 

select a.姓名,b.成績 
from student as a 
inner join score as b on a.學號=b.學號
inner join course as c on b.課程號 =c.課程號 
inner join teacher as d on c.教師號 = d.教師號 
where d.教師姓名 = '孟扎扎'
order by b.成績 desc limit 1;

-查詢至少有一門課與學號爲“0001”的學生所學課程相同的學生的學號和姓名

select 學號 ,姓名 
from student 
where 學號 in
(select distinct(學號) from score where 課程號 in 
(select 課程號 from score where 學號=0001))
 and 學號 !=0001;

 -按平均成績從高到低顯示所有學生的所有課程的成績以及平均成績

【知識點】多表連接 新建字段 ,思路如圖

select a.學號,avg(a.成績 ),
max(case when b.課程名稱  = '數學' then a.成績 else null end ) as '數學',
max(case when b.課程名稱  = '語文' then a.成績 else null end ) as '語文',
max(case when b.課程名稱  = '英語' then a.成績 else null end ) as '英語'
from score as a
inner join course as b 
on a.課程號 =b.課程號 
group by a.學號 ;

4.SQL高級功能


-查詢學生平均成績及其名次

【知識點】窗口函數排名思路如圖

 

select 學號 ,avg(成績),
row_number () over( order by avg(成績) desc)
from score
group by 學號  ;

-按各科成績進行排序,並顯示排名

select 課程號 ,
row_number () over(partition by 課程號 order by 成績 )
from score ;

-查詢每門功成績最好的前兩名學生姓名

【知識點】窗口函數排名+多表連接+條件

 

select a.課程號 ,b.姓名 ,a.成績,a.ranking from (
select 課程號 ,學號 ,成績 ,
row_number () over(partition by 課程號 order by 成績 desc) as ranking
from  score) as a 
inner join student as b on a.學號 =b.學號 
where a.ranking <3 ;

 

-查詢所有課程的成績第2名到第3名的學生信息及該課程成績(與上一題相似)

 

select b.姓名 ,a.課程號 ,a.成績 
from (
select 課程號 ,學號 ,成績 ,
row_number () over( partition by 課程號 order by 成績 desc) as ranking
from  score ) as a 
inner join student as b 
on a.學號 =b.學號 
where a.ranking in( 2,3) ;

-查詢各科成績前三名的記錄(不考慮成績並列情況)與上一題相似)

 

select b.姓名 ,a.課程號 ,a.成績 
from (
select 課程號 ,學號 ,成績 ,
row_number () over( partition by 課程號 order by 成績 desc) as 'ranking'
from  score ) as a 
inner join student as b 
on a.學號 =b.學號 
where a.ranking <4 ;

這些題要融會貫通,以後碰到類似的面試題都可以找到對應場景的使用案例。

推薦:如何從零學會sql?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章