已知有如下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?