--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 分數
測試數據
-- 學生表?Student
create table Student(Sid varchar(10),Sname nvarchar(10),Sage datetime,Ssex nvarchar(10))
insert into Student values('01' , N'趙雷' , '1990-01-01' , N'男')
insert into Student values('02' , N'錢電' , '1990-12-21' , N'男')
insert into Student values('03' , N'孫風' , '1990-05-20' , N'男')
insert into Student values('04' , N'李雲' , '1990-08-06' , N'男')
insert into Student values('05' , N'周梅' , '1991-12-01' , N'女')
insert into Student values('06' , N'吳蘭' , '1992-03-01' , N'女')
insert into Student values('07' , N'鄭竹' , '1989-07-01' , N'女')
insert into Student values('08' , N'王菊' , '1990-01-20' , N'女')
-- 科目表 Course
create table Course(Cid varchar(10),Cname nvarchar(10),Tid varchar(10))
insert into Course values('01' , N'語文' , '02')
insert into Course values('02' , N'數學' , '01')
insert into Course values('03' , N'英語' , '03')
-- --教師表 Teacher
create table Teacher(Tid varchar(10),Tname nvarchar(10))
insert into Teacher values('01', N'張三')
insert into Teacher values('02', N'李四')
insert into Teacher values('03', N'王五')
-- 成績表 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 "課程成績高的學生的信息及課程分數
select distinct a.*,b.score as 01score,c.score as 02score
from student a inner join sc b on a.`SId`=b.`SId`
inner join sc c on b.`SId`=c.`SId`
where b.score > c.score
and b.`CId`=01
and c.`CId`=02
-- 1.1 查詢同時存在" 01 "課程和" 02 "課程的情況
select distinct a.*,b.score as 01score,c.score as 02score
from student a inner join sc b on a.`SId`=b.`SId`
inner join sc c on b.`SId`=c.`SId`
where b.`CId`=01
and c.`CId`=02
-- 1.2 查詢存在" 01 "課程但可能不存在" 02 "課程的情況(不存在時顯示為 null )
select * from
(select * from sc where sc.`CId`=02) as a
right join
(select * from sc where sc.`CId`=01) as b
on a.sid = b.sid
-- 1.3 查詢不存在" 01 "課程但存在" 02 "課程的情況
select a.*,b.*
from sc a join sc b on a.`SId` = b.`SId`
where a.`CId` != 01 and b.`CId` = 02
-- 2. 查詢平均成績大於等於 60 分的同學的學生編號和學生姓名和平均成績
select a.`Sname`,avg(b.score) as avgScore
from student a join sc b on a.`SId`=b.`SId`
group by a.`SId`
having avg(b.score) > 60
-- 3. 查詢在 SC 表存在成績的學生信息
select distinct a.*
from student a join sc b on a.`SId` = b.`SId`
-- 4. 查詢所有同學的學生編號、學生姓名、選課總數、所有課程的總成績(沒成績的顯示為 null )
select a.*,sum(b.score) as sumScore
from student a left join sc b on a.`SId`=b.`SId`
group by a.`SId`
order by sum(b.score) desc
-- 4.1 查有成績的學生信息
select distinct a.*
from student a join sc b on a.`SId`=b.`SId`
----
select *
from student a where exists (select sc.cid from sc where a.`SId`=sc.sid)
---
select *
from student a where a.`SId` in (select sc.sid from sc)
-- 5. 查詢「李」姓老師的數量?
select a.*,count(*) as sum
from teacher a
where a.`Tname` like '李%'
-- 6. 查詢學過「張三」老師授課的同學的信息?
select a.*
from student a,sc b,course c,teacher d
where a.`SId` = b.sid
and b.cid = c.`CId`
and c.`TId` = d.`Tid`
and d.`Tname` ='張三'
-----------
select a.*
from student a join sc b on a.`SId`=b.`SId`
join course c on b.`CId` = c.`CId`
join teacher d on c.`TId` = d.`Tid`
where d.`Tname`='張三'
-- 7. 查詢沒有學全所有課程的同學的信息?
select a.*,count(*)
from student a join sc b on a.`SId`=b.`SId`
join course c on b.`CId` = c.`CId`
group by a.`SId`
-- having count(*) >0
having count(*) < (select count(*) from course)
-- 8. 查詢至少有一門課與學號為" 01 "的同學所學相同的同學的信息?
select distinct a.*
from student a join sc b on a.`SId` = b.`sId`
join sc c on b.`CId`= c.`CId`
where c.`SId` = 01 and a.`SId` != 01
-- 9. 查詢和" 01 "號的同學學習的課程完全相同的其他同學的信息?
select a.*
from student a join sc b on a.`SId`=b.`SId`
where b.`CId` in (
select c.`CId` from sc c where c.`SId` = 01
)
group by a.`SId`
having count(b.`CId`) = (select count(sc.`CId`) from sc where sc.sid=01)
-- 10. 查詢沒學過"張三"老師講授的任一門課程的學生姓名?
select distinct a.*
from student a join sc b on a.`SId`=b.`SId`
join course c on b.`CId` = c.`CId`
join teacher d on c.`TId` = d.`Tid`
where d.`Tname`!='張三'
-- 11. 查詢兩門及其以上不及格課程的同學的學號,姓名及其平均成績?
select a.`SId`,a.`Sname`,avg(b.score)
from student a join sc b on a.`SId`=b.`SId`
where b.score<60
group by a.`SId`
having count(*) > 1
-- 12. 檢索" 01 "課程分數小於 60,按分數降序排列的學生信息
select a.`SId`,a.`Sname`,avg(b.score)
from student a join sc b on a.`SId`=b.`SId`
where b.`CId`=01 and b.score<60
order by b.score desc
-- 13. 按平均成績從高到低顯示所有學生的所有課程的成績以及平均成績
select * from sc b
join (
select c.`SId`,avg(c.score) as avsc
from sc c
group by c.score
) d
on b.`SId` = d.sid
order by avsc desc
-- 14.查詢各科成績最高分、最低分和平均分:
-- 以如下形式顯示:課程 ID,課程 name,最高分,最低分,平均分,及格率,中等率,優良率,優秀率
-- 及格為>=60,中等為:70-80,優良為:80-90,優秀為:>=90
-- 要求輸出課程號和選修人數,查詢結果按人數降序排列,若人數相同,按課程號升序排列
select
a.cou_id,
max(a.sco_degree) as 最高分,
min(a.sco_degree) as 最低分,
avg(a.sco_degree) as 平均分,
count(*) as 選修人數,
sum(case when a.sco_degree>=60 then 1 else 0 end)/count(*) as 及格率,
sum(case when a.sco_degree>=70 and a.sco_degree<80 then 1 else 0 end)/count(*) as 中等率,
sum(case when a.sco_degree>=80 and a.sco_degree<90 then 1 else 0 end)/count(*) as 優良率,
sum(case when a.sco_degree>=90 then 1 else 0 end)/count(*) as 優秀率
from score a
group by a.cou_id
order by count(*) desc,a.cou_id
-- 15.按各科成績進行排序,並顯示排名, Score 重復時保留名次空缺
-- 用sc中的score和自己進行對比,來計算“比當前分數高的分數有幾個
select a.cou_id,a.stu_id,a.sco_degree,count(b.sco_degree)+1 as rank
from score a
left join score b
on a.sco_degree < b.sco_degree and a.cou_id = b.cou_id
group by a.stu_id,a.cou_id,a.sco_degree
order by a.cou_id,rank asc
select cou_id,stu_id,sco_degree,row_number()over(partition by cou_id order by sco_degree desc) rank from score
order by cou_id,rank
select cou_id,stu_id,sco_degree,rank()over(partition by cou_id order by sco_degree desc)as rank from score
order by cou_id,rank
select cou_id,stu_id,sco_degree,dense_rank()over(partition by cou_id order by sco_degree desc)as rank from score
order by cou_id,rank
-- 15.1 按各科成績進行排序,並顯示排名, Score 重復時合並名次
select cou_id,stu_id,sco_degree,dense_rank()over(partition by cou_id order by sco_degree desc)as rank from score
order by cou_id,rank
-- 查詢學生的總成績,並進行排名,總分重復時不保留名次空缺
set @crank = 0;
select b.stu_id, total,@crank := @crank +1 as rank
from (
select a.stu_id,sum(a.sco_degree) as total
from score a
group by a.stu_id
order by total desc
) b
select b.*,dense_rank()over(order by b.total desc) as rank from(
select stu_id,sum(sco_degree) as total from score group by stu_id
) b
order by rank
-- 16.1 查詢學生的總成績,並進行排名,總分重復時不保留名次空缺
select b.*,rank()over(order by b.total desc) as rank from(
select stu_id,sum(sco_degree) as total from score group by stu_id
) b
order by rank
-- 17.統計各科成績各分數段人數:課程編號,課程名稱,[100-85],[85-70],[70-60],[60-0] 及所占百分比
select course.cou_name, course.cou_id,
sum(case when sc.sco_degree<=100 and sc.sco_degree>85 then 1 else 0 end) as "[100-85]",
sum(case when sc.sco_degree<=85 and sc.sco_degree>70 then 1 else 0 end) as "[85-70]",
sum(case when sc.sco_degree<=70 and sc.sco_degree>60 then 1 else 0 end) as "[70-60]",
sum(case when sc.sco_degree<=60 and sc.sco_degree>0 then 1 else 0 end) as "[60-0]"
from score as sc left join course
on sc.cou_id = course.cou_id
group by sc.cou_id;
-- 18.查詢各科成績前三名的記錄
-- 計算比自己分數大的記錄有幾條,如果小於3 就select
select a.cou_id,a.stu_id,a.sco_degree
from score a
where (
select count(*) from score as b
where b.cou_id = a.cou_id and a.sco_degree <b.sco_degree
)< 3
order by a.cou_id asc, a.sco_degree desc;
-- 列出同一門課內所有分數比較的情況
select a.cou_id,a.stu_id,a.sco_degree
from score a
left join score b on a.cou_id = b.cou_id and a.sco_degree< b.sco_degree
group by a.cou_id,a.stu_id
having count(b.cou_id) <3
order by a.cou_id
--
select c.cou_id,c.stu_id,c.sco_degree
from(
select *,rank()over (partition by a.cou_id order by sco_degree desc) b
from score a
) c
where c.b<=3
order by c.cou_id,c.sco_degree desc
-- 19.查詢每門課程被選修的學生數
select a.cou_id,count(a.stu_id) as num
from score a
group by a.cou_id
-- 20.查詢出只選修兩門課程的學生學號和姓名
select a.stu_id,a.stu_name
from student a
where a.stu_id in (
select b.stu_id
from score b
group by b.stu_id
having count(*) = 2
)
select a.stu_id,a.stu_name
from student a inner join score b on a.stu_id = b.stu_id
group by a.stu_id
having count(*)=2
-- 21.查詢男生、女生人數
select a.stu_sex,count(8)
from student a
group by a.stu_sex
-- 22.查詢名字中含有「風」字的學生信息
select *
from student
where stu_name like '%風%'
-- 23.查詢同名同性學生名單,並統計同名人數
select stu_name, count(*) from student
group by stu_name
-- 24.查詢 1990 年出生的學生名單
select stu_name,stu_birthday
from student
where year(stu_birthday) = 1990
-- 25.查詢每門課程的平均成績,結果按平均成績降序排列,平均成績相同時,按課程編號升序排列
select a.cou_id,avg(a.sco_degree) as avcs
from score a
group by a.cou_id
order by avcs desc,a.cou_id
-- 26.查詢平均成績大於等於 85 的所有學生的學號、姓名和平均成績
select a.stu_id,a.stu_name,avg(b.sco_degree)
from student as a inner join score as b on a.stu_id = b.stu_id
group by a.stu_id
having avg(b.sco_degree) >=85
-- 27.查詢課程名稱為「數學」,且分數低於 60 的學生姓名和分數
select a.stu_id,a.stu_name,b.sco_degree
from student as a inner join score as b on a.stu_id = b.stu_id
inner join course as c on c.cou_id = b.cou_id
where c.cou_name="數學"
and b.sco_degree <60
-- 28.查詢所有學生的課程及分數情況(存在學生沒成績,沒選課的情況)
select a.stu_id,a.stu_name,b.sco_degree
from student as a left join score as b on a.stu_id = b.stu_id
-- 29.查詢任何一門課程成績在 70 分以上的姓名、課程名稱和分數
select a.stu_id,a.stu_name,b.sco_degree
from student as a left join score as b on a.stu_id = b.stu_id
where b.sco_degree>70
-- 30.查詢不及格的課程
select * from score
where sco_degree< 60
group by cou_id;
-- 31.查詢課程編號為 01 且課程成績在 80 分以上的學生的學號和姓名
select a.stu_id,a.stu_name,b.cou_id,b.sco_degree
from student as a left join score as b on a.stu_id = b.stu_id
where b.sco_degree>=80 and b.cou_id =01
-- 32.求每門課程的學生人數
select b.stu_id,count(*)as 學生人數
from score b
group by b.cou_id
-- 33.成績不重復,查詢選修「張三」老師所授課程的學生中,成績最高的學生信息及其成績
select * from score
where score.cou_id =(
select b.cou_id from course b where b.tea_id = (
select teacher.tea_id from teacher where teacher.tea_name ='張三'
)
)
order by score.sco_degree desc
limit 1
-- 34.成績有重復的情況下,查詢選修「張三」老師所授課程的學生中,成績最高的學生信息及其成績
select * from (
select z.cou_id,z.stu_id,z.sco_degree,dense_rank()over(order by z.sco_degree desc) as rank from score z
where z.cou_id =(
select b.cou_id from course b where b.tea_id = (
select teacher.tea_id from teacher where teacher.tea_name ='張三'
)
)
) y
where y.rank = 1
-- 35.查詢不同課程成績相同的學生的學生編號、課程編號、學生成績
select *
from score a inner join score b on a.stu_id = b.stu_id
where a.cou_id != b.cou_id
and a.sco_degree = b.sco_degree
group by a.cou_id,a.stu_id
-- 36.查詢每門功成績最好的前兩名
select *
from (
select *, row_number()over(partition by b.cou_id order by b.sco_degree desc ) as rank from score b
) c
where c.rank <3
order by c.cou_id,c.stu_id
-- 37.統計每門課程的學生選修人數(超過 5 人的課程才統計)。
select a.cou_id,count(*) as num
from score a
group by a.cou_id
having count(*)>5
-- 38.檢索至少選修兩門課程的學生學號
-- 39.查詢選修了全部課程的學生信息
-- 40.查詢各學生的年齡,只按年份來算
select student.stu_id as 學生編號,student.stu_name as 學生姓名,
timestampdiff(YEAR,student.stu_birthday,curdate()) as 學生年齡
from student
-- 41.按照出生日期來算,當前月日 < 出生年月的月日則,年齡減一
-- 42.查詢本周過生日的學生
-- 43.查詢下周過生日的學生
select *
from student
where weekofyear(student.stu_birthday)=weekofyear(curdate())+1;
-- 44.查詢本月過生日的學生
-- 45.查詢下月過生日的學生
select *
from student
where month(student.stu_birthday)=month(curdate())+1;