SQL學生選課場景練習
題目轉載自50道SQL練習題,簡單的學生選課場景。
我使用的是SQLite,與MYSQL除了函數用法不同外其他基本相同。數據表
--1.學生表
Student(SId,Sname,Sage,Ssex)--SId 學生編號,Sname 學生姓名,Sage 出生年月,Ssex 學生性別
--2.課程表
Course(CId,Cname,TId)--CId 課程編號,Cname 課程名稱,TId 教師編號--3.教師表
Teacher(TId,Tname)--TId 教師編號,Tname 教師姓名--4.成績表
SC(SId,CId,score)--SId 學生編號,CId 課程編號,score 分數創建測試數據
學生表 Studentcreate table Student(SId varchar(10),Sname varchar(10),Sage datetime,Ssex varchar(10));insert into Student values(01 , 趙雷 , 1990-01-01 , 男);insert into Student values(02 , 錢電 , 1990-12-21 , 男);insert into Student values(03 , 孫風 , 1990-05-20 , 男);insert into Student values(04 , 李雲 , 1990-08-06 , 男);insert into Student values(05 , 周梅 , 1991-12-01 , 女);insert into Student values(06 , 吳蘭 , 1992-03-01 , 女);insert into Student values(07 , 鄭竹 , 1989-07-01 , 女);insert into Student values(09 , 張三 , 2017-12-20 , 女);insert into Student values(10 , 李四 , 2017-12-25 , 女);insert into Student values(11 , 李四 , 2017-12-30 , 女);insert into Student values(12 , 趙六 , 2017-01-01 , 女);insert into Student values(13 , 孫七 , 2018-01-01 , 女);
create table Course(CId varchar(10),Cname nvarchar(10),TId varchar(10))insert into Course values(01 , 語文 , 02)insert into Course values(02 , 數學 , 01)insert into Course values(03 , 英語 , 03)
教師表 Teacher
create table Teacher(TId varchar(10),Tname varchar(10))insert into Teacher values(01 , 張三)insert into Teacher values(02 , 李四)insert into Teacher values(03 , 王五)
成績表 SC
create table SC(SId varchar(10),CId varchar(10),score decimal(18,1))insert into SC values(01 , 01 , 80)insert into SC values(01 , 02 , 90)insert into SC values(01 , 03 , 99)insert into SC values(02 , 01 , 70)insert into SC values(02 , 02 , 60)insert into SC values(02 , 03 , 80)insert into SC values(03 , 01 , 80)insert into SC values(03 , 02 , 80)insert into SC values(03 , 03 , 80)insert into SC values(04 , 01 , 50)insert into SC values(04 , 02 , 30)insert into SC values(04 , 03 , 20)insert into SC values(05 , 01 , 76)insert into SC values(05 , 02 , 87)insert into SC values(06 , 01 , 31)insert into SC values(06 , 03 , 34)insert into SC values(07 , 02 , 89)insert into SC values(07 , 03 , 98)
練習題目
1. 查詢" 01 "課程比" 02 "課程成績高的學生的信息及課程分數1.1 查詢同時存在" 01 "課程和" 02 "課程的情況1.2 查詢存在" 01 "課程但可能不存在" 02 "課程的情況(不存在時顯示為 null )
1.3 查詢不存在" 01 "課程但存在" 02 "課程的情況2. 查詢平均成績大於等於 60 分的同學的學生編號和學生姓名和平均成績3. 查詢在 SC 表存在成績的學生信息4. 查詢所有同學的學生編號、學生姓名、選課總數、所有課程的總成績(沒成績的顯示為 null )4.1 查有成績的學生信息5. 查詢「李」姓老師的數量6. 查詢學過「張三」老師授課的同學的信息7. 查詢沒有學全所有課程的同學的信息8. 查詢至少有一門課與學號為" 01 "的同學所學相同的同學的信息9. 查詢和" 01 "號的同學學習的課程 完全相同的其他同學的信息
10. 查詢沒學過"張三"老師講授的任一門課程的學生姓名11. 查詢兩門及其以上不及格課程的同學的學號,姓名及其平均成績12. 檢索" 01 "課程分數小於 60,按分數降序排列的學生信息13. 按平均成績從高到低顯示所有學生的所有課程的成績以及平均成績14. 查詢各科成績最高分、最低分和平均分:以如下形式顯示:課程 ID,課程 name,最高分,最低分,平均分,及格率,中等率,優良率,優秀率及格為>=60,中等為:70-80,優良為:80-90,優秀為:>=90要求輸出課程號和選修人數,查詢結果按人數降序排列,若人數相同,按課程號升序排列15. 按各科成績進行排序,並顯示排名, Score 重複時保留名次空缺15.1 按各科成績進行排序,並顯示排名, Score 重複時合併名次
16. 查詢學生的總成績,並進行排名,總分重複時保留名次空缺16.1 查詢學生的總成績,並進行排名,總分重複時不保留名次空缺17. 統計各科成績各分數段人數:課程編號,課程名稱,[100-85],[85-70],[70-60],[60-0] 及所佔百分比18. 查詢各科成績前三名的記錄19. 查詢每門課程被選修的學生數20. 查詢出只選修兩門課程的學生學號和姓名21. 查詢男生、女生人數22. 查詢名字中含有「風」字的學生信息23. 查詢同名同性學生名單,並統計同名人數24. 查詢 1990 年出生的學生名單
25. 查詢每門課程的平均成績,結果按平均成績降序排列,平均成績相同時,按課程編號升序排列26. 查詢平均成績大於等於 85 的所有學生的學號、姓名和平均成績27. 查詢課程名稱為「數學」,且分數低於 60 的學生姓名和分數28. 查詢所有學生的課程及分數情況(存在學生沒成績,沒選課的情況)29. 查詢任何一門課程成績在 70 分以上的姓名、課程名稱和分數30. 查詢不及格的課程31. 查詢課程編號為 01 且課程成績在 80 分以上的學生的學號和姓名32. 求每門課程的學生人數33. 成績不重複,查詢選修「張三」老師所授課程的學生中,成績最高的學生信息及其成績34. 成績有重複的情況下,查詢選修「張三」老師所授課程的學生中,成績最高的學生信息及其成績
35. 查詢不同課程成績相同的學生的學生編號、課程編號、學生成績36. 查詢每門功成績最好的前兩名37. 統計每門課程的學生選修人數(超過 5 人的課程才統計)。38. 檢索至少選修兩門課程的學生學號39. 查詢選修了全部課程的學生信息40. 查詢各學生的年齡,只按年份來算41. 按照出生日期來算,當前月日 < 出生年月的月日則,年齡減一42. 查詢本周過生日的學生43. 查詢下周過生日的學生44. 查詢本月過生日的學生
45. 查詢下月過生日的學生1.查詢" 01 "課程比" 02 "課程成績高的學生的信息及課程分數
select sc1.Sid, sc1.score, sc2.scorefrom SC sc1 left join SC sc2 on sc1.SId=sc2.SIdwhere sc1.CId=01 and sc2.CId=02 and sc1.score>sc2.score
1.1 查詢同時存在" 01 "課程和" 02 "課程的情況
select sc1.Sid, sc1.score, sc2.scorefrom SC sc1 left join SC sc2 on sc1.SId=sc2.SIdwhere sc1.CId=01 and sc2.CId=02
1.2 查詢存在" 01 "課程但可能不存在" 02 "課程的情況(不存在時顯示為 null )
select sc1.SId, sc1.score, sc2.scorefrom SC sc1 left join SC sc2 on sc1.SId=sc2.SId and sc2.CId=02where sc1.CId=01
1.3 查詢不存在" 01 "課程但存在" 02 "課程的情況
select *from SCwhere SId not in (select SId from SC where CId=01) and CId=02
2. 查詢平均成績大於等於 60 分的同學的學生編號和學生姓名和平均成績
select c.SId, s.Sname, avg(c.score)from SC c inner join Student s on c.SId=s.SIdgroup by c.SIdhaving avg(c.score)>=60
3. 查詢在 SC 表存在成績的學生信息
select DISTINCT student.*from student ,scwhere student.SId=sc.SId
4.查詢所有同學的學生編號、學生姓名、選課總數、所有課程的總成績(沒成績的顯示為null)
select s.SId, s.Sname, count(c.CId), sum(score)from Student s left join SC c on s.SId=c.SIdgroup by c.SId
4.1 查有成績的學生信息
select distinct s.*from Student s inner join SC con s.SId=c.SId
5. 查詢「李」姓老師的數量
select count(*)from Teacher twhere t.Tname like 李%
6. 查詢學過「張三」老師授課的同學的信息
select distinct s.*from Student sinner join SC sc on s.SId=sc.SIdinner join Course c on sc.CId=c.CIdinner join Teacher t on c.TId=t.TIdwhere t.Tname=張三
7. 查詢沒有學全所有課程的同學的信息
select student.*from studentwhere student.SId not in ( select sc.SIdfrom scgroup by sc.SIdhaving count(*)=(select count(CId) from course))
8. 查詢至少有一門課與學號為" 01 "的同學所學相同的同學的信息
select DISTINCT student.*from sc ,studentwhere sc.CId in (select CId from sc where sc.SId=01)and sc.SId=student.SId and sc.SId!=01
9.查詢和" 01 "號的同學學習的課程完全相同的其他同學的信息
select s.*from sc, (select CId from SC where SId=01) s1, Student swhere sc.CId=s1.CId and s.SId=sc.SId and s.SId!=01group by sc.SIdhaving count(sc.CId)=3
10.查詢沒學過"張三"老師講授的任一門課程的學生姓名
select *from Student swhere s.SId not in(select distinct s.SIdfrom Student s left join sc on s.SId=sc.SIdleft join Course c on sc.CId=c.CIdleft join Teacher t on c.TId=t.TIdwhere t.Tname=張三)
11.查詢兩門及其以上不及格課程的同學的學號,姓名及其平均成績
select s.SId, s.Sname, avg(sc1.score)from (select * from sc where score<60) sc1, Student swhere sc1.SId=s.SIdgroup by sc1.SIdhaving count(sc1.CId)>1
12. 檢索" 01 "課程分數小於 60,按分數降序排列的學生信息
select s.*from Student s, scwhere sc.CId=01 and sc.score<60 and s.SId=sc.SIdorder by sc.score desc
13. 按平均成績從高到低顯示所有學生的所有課程的成績以及平均成績
select SId, max(case when CId=01 then score end) as 01, max(case when CId=02 then score end) as 02, max(case when CId=03 then score end) as 03, avg(score)from scgroup by SIdorder by avg(score) desc
課程非常多或動態變化時此方法不可行。
14. 查詢各科成績最高分、最低分和平均分:
以如下形式顯示:課程 ID,課程 name,最高分,最低分,平均分,及格率,中等率,優良率,優秀率及格為>=60,中等為:70-80,優良為:80-90,優秀為:>=90要求輸出課程號和選修人數,查詢結果按人數降序排列,若人數相同,按課程號升序排列select sc.CId 課程號, max(sc.score) 最高分, min(sc.score) 最低分, round(avg(sc.score),2) 平均分, count(sc.score) 選修人數, round(count(case when sc.score>=60 then 1 else null end)*1.0/count(sc.score),2) 及格率, round(count(case when sc.score>=70 and sc.score<80 then 1 else null end)*1.0/count(sc.score),2) 中等率, round(count(case when sc.score>=80 and sc.score<90 then 1 else null end)*1.0/count(sc.score),2) 優良率, round(count(case when sc.score>=90 then 1 else null end)*1.0/count(sc.score),2) 優秀率from scgroup by sc.CIdorder by 選修人數 desc, 課程號
15. 按各科成績進行排序,並顯示排名, Score 重複時保留名次空缺
select sc.SId, sc.CId, sc.score, tp.rankfrom sc left join (select SId, CId, (select count(sc2.score)+1 from sc sc2 where sc1.CId=sc2.CId and sc2.score>sc1.score) rank from sc sc1) tpon sc.SId=tp.SId and sc.CId=tp.CIdorder by sc.CId, rank
15.1 按各科成績進行排序,並顯示排名, Score 重複時合併名次
select sc.SId, sc.CId, sc.score, tp.rankfrom sc left join (select SId, CId, (select count(distinct sc2.score)+1 from sc sc2 where sc1.CId=sc2.CId and sc2.score>sc1.score) rank from sc sc1) tpon sc.SId=tp.SId and sc.CId=tp.CIdorder by sc.CId, rank
16. 查詢學生的總成績,並進行排名,總分重複時保留名次空缺
select k1.*, count(k2.total) rankfrom (select SId, sum(score) total from sc group by SId) k1, (select sum(score) total from sc group by SId) k2where k2.total>=k1.totalgroup by k1.SIdorder by rank
16.1 查詢學生的總成績,並進行排名,總分重複時不保留名次空缺
select k1.*, count(distinct k2.total) rankfrom (select SId, sum(score) total from sc group by SId) k1, (select sum(score) total from sc group by SId) k2where k2.total>=k1.totalgroup by k1.SIdorder by rank
17. 統計各科成績各分數段人數:課程編號,課程名稱,[100-85],[85-70],[70-60],[60-0] 及所佔百分比
select c.CId 課程編號, c.Cname 課程名稱, count(case when sc.score>=85 then 1 else null end) as [100,85]人數, round(count(case when sc.score>=85 then 1 else null end)*1.0/count(sc.score),2) as [100,85]佔比, count(case when sc.score>=70 and sc.score<85 then 1 else null end) as (85,70]人數, round(count(case when sc.score>=70 and sc.score<85 then 1 else null end)*1.0/count(sc.score),2) as (85,70]佔比, count(case when sc.score>=60 and sc.score<70 then 1 else null end) as (70,60]人數, round(count(case when sc.score>=60 and sc.score<70 then 1 else null end)*1.0/count(sc.score),2) as (70,60]佔比, count(case when sc.score<60 then 1 else null end) as (60,0]人數, round(count(case when sc.score<60 then 1 else null end)*1.0/count(sc.score),2) as (60,0]佔比from Course c left join scon c.CId=sc.CIdgroup by c.CId
18. 查詢各科成績前三名的記錄
select CId, SId, scorefrom scwhere (select count(*) from sc sc1 where sc1.CId=sc.CId and sc1.score>sc.score) <3order by CId, score desc
19. 查詢每門課程被選修的學生數
select c.CId, c.Cname, count(*)from Course c, scwhere c.CId=sc.CIdgroup by c.CId
20. 查詢出只選修兩門課程的學生學號和姓名
select s.SId, s.Snamefrom Student s left join sc on s.SId=sc.SIdgroup by s.SIdhaving count(score)=2
21.查詢男生、女生人數
select Ssex, count(*)from Studentgroup by Ssex
22. 查詢名字中含有「風」字的學生信息
select *from Studentwhere Sname like %風%
23.查詢同名同性學生名單,並統計同名人數
select s1.*, amountfrom Student s1inner join (select Sname, Ssex, count(*) amount from Student s2 group by Sname, Ssex having count(*)>1) non s1.Sname=n.Sname and s1.Ssex=n.Ssex
24.查詢 1990 年出生的學生名單
select *from studentwhere date(student.Sage) like 1990%
25.查詢每門課程的平均成績,結果按平均成績降序排列,平均成績相同時,按課程編號升序排列
select CId, round(avg(score),2) averagefrom scgroup by CIdorder by average desc, CId
26.查詢平均成績大於等於 85 的所有學生的學號、姓名和平均成績
select s.SId, s.Sname, round(avg(score),2) averagefrom sc inner join Student son sc.SId=s.SIdgroup by sc.SIdhaving average>=85
27. 查詢課程名稱為「數學」,且分數低於 60 的學生姓名和分數
select Sname, scorefrom Course cinner join sc on c.Cname=數學 and c.CId=sc.CIdinner join Student s on sc.SId=s.SIdwhere score<60
28. 查詢所有學生的課程及分數情況(存在學生沒成績,沒選課的情況)
select s.SId, s.Sname, max(case when sc.CId=01 then score else null end) as 語文』, max(case when sc.CId=02 then score else null end) as 數學』, max(case when sc.CId=03 then score else null end) as 『英語 from Student s left join sc on s.SId=sc.SIdgroup by s.SId
29. 查詢任何一門課程成績在 70 分以上的姓名、課程名稱和分數
select s.Sname, c.Cname, sc.scorefrom Student s, sc, Course c, (select SId from sc group by SId having min(score)>70) nwhere n.SId=s.SId and sc.CId=c.CId and n.SId=sc.SId
30.查詢存在不及格的課程
select distinct SIdfrom scwhere score<60
31.查詢課程編號為 01 且課程成績在 80 分以上的學生的學號和姓名
select s.SId, s.Snamefrom sc, Student swhere sc.CId=01 and sc.Score>=80 and sc.SId=s.SId
32. 求每門課程的學生人數
select CId, count(*)from scgroup by CId
33. 成績不重複,查詢選修「張三」老師所授課程的學生中,成績最高的學生信息及其成績
select s.*, sc.scorefrom Teacher tleft join Course c on t.Tname=張三 and t.TId=c.TIdleft join SC on c.CId=sc.CIdleft join Student s on sc.SId=s.SIdorder by sc.score desclimit 1
34. 成績有重複的情況下,查詢選修「張三」老師所授課程的學生中,成績最高的學生信息及其成績
select s.*, sc.scorefrom (select sc.CId, sc.score from sc, Course c, Teacher t where t.Tname=張三 and t.TId=c.TId and sc.CId=c.CId order by sc.score desc limit 1) ms, sc, Student swhere ms.score=sc.score and ms.CId=sc.CId and sc.SId=s.SId
35. 查詢不同課程成績相同的學生的學生編號、課程編號、學生成績
select distinct sc1.*from sc sc1 inner join sc sc2on sc1.SId=sc2.SId and sc1.score=sc2.score and sc1.CId!=sc2.CId
36.查詢每門功成績最好的前兩名
select *from scwhere (select count(*) from sc sc1 where sc1.CId=sc.CId and sc1.score>sc.score)<2order by CId
37.統計每門課程的學生選修人數(超過 5 人的課程才統計)
select CId, count(*)from scgroup by CIdhaving count(*)>5
38.檢索至少選修兩門課程的學生學號
select SIdfrom scgroup by SIdhaving count(*)>=2
39. 查詢選修了全部課程的學生信息
select s.*from Student s left join sc on s.SId=sc.SIdgroup by s.SIdhaving count(*)=(select distinct count(*) from Course)
40.查詢各學生的年齡,只按年份來算
select SId as 學生編號, Sname as 學生姓名, date(now)-strftime(%Y,Sage) as 學生年齡from student
41. 按照出生日期來算,當前月日 < 出生年月的月日則,年齡減一
select student.SId as 學生編號, student.Sname as 學生姓名, date(now)-strftime(Sage) as 學生年齡from student
42.查詢本周過生日的學生
select *from studentwhere strftime(%W,Sage)=strftime(%W,date(now))
43. 查詢下周過生日的學生
select *from studentwhere cast(strftime(%W,Sage) as int)=cast(strftime(%W,date(now)) as int)+1
44.查詢本月過生日的學生
select *from studentwhere cast(strftime(%m,Sage) as int)=cast(strftime(%m,date(now)) as int)
45.查詢下月過生日的學生
select *from studentwhere cast(strftime(%m,Sage) as int)=cast(strftime(%m,date(now)) as int)+1
歡迎指正。
推薦閱讀:
※當計算欄位邂逅子查詢
※利用SQL進行用戶消費行為分析
※Cross Apply 與 Inner Join 的對抗
※什麼是最好的oracle sql 開發工具?
※Sqli labs系列-less-2 詳細篇
TAG:SQL |