mysql資料庫練習
測試表格
--1.學生表
Student(S#,Sname,Sage,Ssex)
--S# 學生編號,Sname 學生姓名,Sage 出生年月,Ssex 學生性別
--2.課程表
Course(C#,Cname,T#)
--C# --課程編號,Cname 課程名稱,T# 教師編號
--3.教師表
Teacher(T#,Tname)
--T# 教師編號,Tname 教師姓名
--4.成績表
SC(S#,C#,score)
--S# 學生編號,C# 課程編號,score 分數
建立測試資料
學生表 Student
create table Student(S# 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(C# varchar(10),Cname nvarchar(10),T# 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(T# 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(S# varchar(10),C# 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、查詢“001”課程比“002”課程成績高的所有學生的學號
select a.S# from (select S#,score from SC where C#='001')a,
(select s#,score from SC where c#='002')b Where a.score>b.score and a.s# = b.s#;
2、查詢平均成績大於60分的同學的學號和平均成績
select S#, avg(score) from sc group by S# having avg(score)>60
3、查詢所有同學的學號、姓名、選課數、總成績
select student.S_id, student.Sname, count(sc.C_id), sum(score) from student
left join SC on student.S_id = SC.S_id group by Student.S_id, Sname
4、查詢姓‘李’的老師的個數:
select count(distinct(Tname))
from teacher
where tname like '李%';
5、查詢沒有學過“葉平”老師可的同學的學號、姓名:
select student.S#, student.Sname
from Student
where S# not in (select distinct(SC.S#) from SC,Course,Teacher
where sc.c#=course.c# AND teacher.T#=course.T# AND Teahcer.Tname ='葉平');
6、查詢學過“葉平”老師所教的所有課的同學的學號、姓名:
select S#,Sname from Student
where S# in (select S# from SC ,Course ,Teacher
where SC.C#=Course.C# and Teacher.T#=Course.T#
and Teacher.Tname='葉平' group by S#
having count(SC.C#)=(select count(C#) from Course,Teacher
where Teacher.T#=Course.T# and Tname='葉平'));
7、查詢學過“011”並且也學過編號“002”課程的同學的學號、姓名:
select Student.S#,Student.Sname
from Student,SC where Student.S#=SC.S#
and SC.C#='001'and
exists( Select * from SC as SC_2 where SC_2.S#=SC.S# and SC_2.C#='002');
8、查詢課程編號“002”的成績比課程編號“001”課程低的所有同學的學號、姓名:
Select S#,Sname
from (select Student.S#,Student.Sname,score ,
(select score from SC SC_2 where SC_2.S#=Student.S# and SC_2.C#='002') score2
from Student,SC
where Student.S#=SC.S# and C#='001') S_2
where score2 < score;
9、查詢所有課程成績小於60的同學的學號、姓名:
select S#, sname
from student
where s# not in
(select student.s# from student, sc where s.s# = sc.s# and score>60);
10、查詢沒有學全所有課的同學的學號、姓名:
select student.s#, student.sname
from student, sc
where student.s#=sc.s#
group by student.s#, student.sname
having count(c#)<(select count(c#) from course);
11、查詢至少有一門課與學號為“1001”同學所學相同的同學的學號和姓名:
select s#, Sname
from Student, SC
where student.s# = sc.s#
and c# in (select c# from SC where s#='1001');
12、查詢至少學過學號為“001”同學所有一門課的其他同學學號和姓名;
select distinct sc.s# , sname
from student, sc
where student.s#=sc.s#
and c# in (select C# from sc where s#='001');
13、把“SC”表中“葉平”老師教的課的成績都更改為此課程的平均成績:
Update Sc Set Score=(Select Avg(s2_Score) From sc s2 Where s2.c#=sc.c#)
Where c# IN
(Select c# From sc cs INNER JOIN Teacher tc ON cs.t#=tc.t# WHERE tname ='葉平')
14、查詢和“1002”號的同學學習的課程完全相同的其他同學學號和姓名:
select s# from sc where c# in
(select c# from sc where s#='1002')
group by s# having count(*)=
(select count(*) from sc where s#='1002');
這個寫法是有問題的,如果“1002”同學的學習課程是其它同學的子集,那麼也會篩選出來;
正確寫法如下:子集且記錄數相同
select t1.s_id from
(select s_id,count(distinct c_id) as cnt1 from sc where c_id in
(select c_id from sc where s_id=2) and s_id <> 2 group by s_id
having count(distinct c_id)=(select count(distinct c_id) from sc where s_id=2)) t1,
(select s_id,count(distinct c_id) as cnt2 from sc group by s_id) t2
where t1.s_id=t2.s_id and t1.cnt1=t2.cnt2
15、刪除學習“葉平”老師課的SC表記錄:
delect sc
from course, Teacher
where course.c#=sc.c#
and course.t#=teacher.t#
and tname='葉平';
16、向SC表中插入一些記錄,這些記錄要求符合以下條件:沒有上過編號“003”課程的同學學號、002號課的平均成績:
Insert SC select S#,'002',
(Select avg(score) from SC where C#='002')
from Student where S# not in (Select S# from SC where C#='002');
17、按平均成績從高到低顯示所有學生的“資料庫”、“企業管理”、“英語”三門的課程成績,按如下形式顯示:學生ID,資料庫,企業管理,英語,有效課程數,有效平均分:
select s_id as 學生ID,
(select score from sc where sc.s_id=t.s_id and c_id=1) as 資料庫,
(select score from sc where sc.s_id=t.s_id and c_id=2) as 企業管理,
(select score from sc where sc.s_id=t.s_id and c_id=3) as 英語,
count(*) as 有效課程數, avg(t.score) as 平均成績,rank() over(order by avg(t.score) desc) as 名次
from sc t
group by s_id
order by avg(t.score) asc
此題很經典,沒做出來。rank over() 裡面是是計算名次的排序;order by是記錄展示的排序
18、查詢各科成績最高和最低的分: 以如下的形式顯示:課程ID,最高分,最低分
select L.c# as 課程ID, L.score as 最高分,
R.score as 最低分
from sc L, sc R
where L.c# = R.c#
and L.score = (select max(IL.score)
from sc IL, student as IM
where L.c#=IL.c# and IM.s#=IL.s#
group by IL.c#)
and R.score = (select min(IR.score)
from sc as IR
where R.c#=IR.c#
group by IR.c#);
select c_id,max(score),min(score) from sc group by c_Id;
19、按各科平均成績從低到高和及格率的百分數從高到低順序:
SELECT t.C# AS 課程號,
max(course.Cname)AS 課程名,
isnull(AVG(score),0) AS 平均成績,
100 * SUM(CASE WHEN isnull(score,0)>=60 THEN 1 ELSE 0 END)/COUNT(*) AS 及格百分數
FROM SC T,Course
where t.C#=course.C#
GROUP BY t.C#
ORDER BY 100 * SUM(CASE WHEN isnull(score,0)>=60 THEN 1 ELSE 0 END)/COUNT(*) DESC
select c_id 課程編號,round(avg(score),2) 平均分,
round(sum(case when score>59 then 1 else 0 end)/count(1)*100.00,2)||'%' 及格率 from sc
group by c_id order by 平均分 asc,及格率 desc;
20、查詢如下課程平均成績和及格率的百分數(用”1行”顯示): 企業管理(001),馬克思(002),OO&UML (003),資料庫(004):
21、查詢不同老師所教不同課程平均分從高到低顯示:
SELECT max(Z.T#) AS 教師ID,
MAX(Z.Tname) AS 教師姓名,
C.C# AS 課程ID,
AVG(Score) AS 平均成績
FROM SC AS T,Course AS C ,Teacher AS Z
where T.C#=C.C# and C.T#=Z.T#
GROUP BY C.C#
ORDER BY AVG(Score) DESC
22、查詢如下課程成績第3名到第6名的學生成績單:企業管理(001),馬克思(002),UML(003),資料庫(004):
23、統計下列各科成績,各分數段人數:課程ID,課程名稱,[100-85],[85-70],[70-60],[ 小於60] :
SELECT SC.C# as 課程ID, Cname as 課程名稱,
SUM(CASE WHEN score BETWEEN 85 AND 100 THEN 1 ELSE 0 END) AS [100 - 85] ,
SUM(CASE WHEN score BETWEEN 70 AND 85 THEN 1 ELSE 0 END) AS [85 - 70],
SUM(CASE WHEN score BETWEEN 60 AND 70 THEN 1 ELSE 0 END) AS [70 - 60],
SUM(CASE WHEN score < 60 THEN 1 ELSE 0 END) AS [60 -]
FROM SC,Course
where SC.C#=Course.C#
GROUP BY SC.C#,Cname;
select c_id 課程ID,
(select cname from course t1 where t1.c_id=t2.c_id) 課程名稱,
count(distinct case when score between 85 and 100 then s_id end ) "[85-100分]人數",
count(distinct case when score between 70 and 85 then s_id end ) "[75-85分]人數",
count(distinct case when score between 60 and 70 then s_id end ) "[60-70]人數",
count(distinct case when score <60 then s_id end ) "小於60分人數"
from sc t2 group by c_id ;
注:這種寫法更好一點,可以排除,同人同科目錯誤錄入了兩條記錄的情況;
24、查詢學生平均成績及其名次:
SELECT 1+(SELECT COUNT( distinct 平均成績)
FROM (SELECT S#,AVG(score) AS 平均成績
FROM SC
GROUP BY S# ) AS T1 WHERE 平均成績 > T2.平均成績) as 名次,
S# as 學生學號,平均成績
FROM (SELECT S#,AVG(score) 平均成績
FROM SC
GROUP BY S# ) AS T2
ORDER BY 平均成績 desc;
select s_id 學號,avg(score) 平均成績,rank() over(order by avg(score) desc) 名次 from sc group by s_id;
25、查詢各科成績前三名的記錄(不考慮成績並列情況):
SELECT t1.S# as 學生ID,t1.C# as 課程ID,Score as 分數
FROM SC t1
WHERE score IN
(SELECT TOP 3 score
FROM SC
WHERE t1.C#= C#
ORDER BY score DESC)
select s_id,c_id,dense_rank() over(partition by c_id order by score desc) rank from sc;
注:oracle沒有top N的寫法;
26、查詢每門課程被選修的學生數:
select c#, count(s#)
from sc
group by c#;
27、查詢出只選修一門課程的全部學生的學號和姓名:
select t2.s_Id,t2.sname from student t2 where t2.s_id
in(select s_Id from sc group by sc.s_id having count(distinct sc.c_id)=1);
select t1.s_id,t2.sname from sc t1,student t2 where t1.s_id=t2.s_id
group by t1.s_id,t2.sname having count(distinct t1.c_id)=1
注:寫法2 可加深對group by的理解,實際根據t1.s_id已經能夠唯一定位,加上t2.sname完全是語法需要
28、查詢男生、女生人數:
select count(Ssex) as 男生人數
from student
group by Ssex
having Ssex='男';
select count(Ssex) as 女生人數
from student
group by Ssex
having Ssex='女';
select (case when ssex='M' then '男' else '女' end) 性別,count(1) 人數 from student group by ssex;
注:注意單引號,資料庫裡只識別單引號。
29、查詢姓“張”的學生名單:
select sname
from student
where sname like '張%';
30、查詢同名同姓的學生名單,並統計同名人數:
select sanme,count(*)
from student
group by sname
havang count(*)>1;
31、1981年出生的學生名單(注:student表中sage列的型別是datetime):
select sname, convert(char(11),DATEPART(year,sage)) as age
from student
where convert(char(11),DATEPART(year,Sage))='1981';
32、查詢平均成績大於85的所有學生的學號、姓名和平均成績:
select Sname,SC.S# ,avg(score)
from Student,SC
where Student.S#=SC.S#
group by SC.S#,Sname
having avg(score)>85;
33、查詢每門課程的平均成績,結果按平均成績升序排序,平均成績相同時,按課程號降序排列:
select C#, avg(score)
from sc
group by c#
order by avg(score), c# desc;
34、查詢課程名稱為“資料庫”,且分數低於60的學生名字和分數:
select sname, isnull(score,0)
from student, sc ,course
where sc.s#=student.s# and sc.c#=course.c# and course.cname='資料庫' and score<60;
35、查詢所有學生的選課情況:
select sc.s#,sc.c#,sname,cname
from sc,student course
where sc.s#=student.s# and sc.c#=course.c#;
36、查詢任何一門課程成績在70分以上的姓名、課程名稱和分數:
select distinct student.s#,student.sname,sc.c#,sc.score
from student,sc
where sc.score>=70 and sc.s#=student.s#;
37、查詢課程和不及格人數,並按課程號從大到小的排列:
select c#
from sc
where score<60
order by c#;
select c_id , count(1) from sc where score < 60 group by c_id order by c_id;
注:很好的考察了對group by 用法的理解
38、查詢課程編號為“003”且課程成績在80分以上的學生的學號和姓名:
select sc.s#,student.sname
from sc,student
where sc.s#=student.s# and score>80 and c#='003';
39、求選了課程的學生人數:
select count(*) from sc;
select count(distinct c_id) from sc where score is not null;
注:感覺這樣更嚴謹
40、查詢選修“葉平”老師所授課程的學生中,成績最高的學生姓名及其成績:
select student.sname,score
from student,sc,course c, teacher
where student.s#=sc.S# and sc.c#=c.c#
and c.T#=teacher.T#
and teacher.tname='葉平'
and sc.score=(select max(score) from sc where c#=c.c#);
select t4.sname 姓名,t3.score 成績 from sc t3,student t4 where t3.s_id=t4.s_id and t3.score=
(select max(score) from sc
where c_id in(select t1.c_id from course t1,teacher t2 where t1.t_id=t2.t_id and t2.tname='葉平'));
注:連線4張表
41、查詢各個課程及相應的選修人數:
select count(*) from sc group by c#;
42、查詢不同課程成績相同的學生和學號、課程號、學生成績:
select distinct a.s#,b.score
from sc a ,sc b
where a.score=b.score
and a.c#<>b.c#;
select t1.* from
sc t1,sc t2 where
t1.score=t2.score and t1.s_id<>t2.s_id and t1.c_id<>t2.c_id order by t1.score;
注:使用自連線的例子
43、查詢每門課程成績最好的前兩名:
select t1.s# as 學生ID,t1.c# 課程ID, Score as 分數
from sc t1
where score in (select top 2 score from sc
where t1.c#=c#
order by score desc)
order by t1.c#;
select (select cname from course where c_id=t1.c_id) 課程名,t2.sname 學生姓名,t1.rank 排名 from
(select c_id,s_id,rank() over(partition by c_id order by score desc) rank from sc) t1,student t2
where t1.s_id=t2.s_id and t1.rank <3
注:partition by 以前沒用過,注意下用法;
44、統計每門課程的學生選修人數(超過10人的課程才統計)。要求輸出課程號和選修人數,查詢結果按人數降序排序,若人數相同,按課程號升序排序:
select c_id,count(distinct s_id) from sc group by c_id
having count(distinct s_id)>10 order by count(distinct s_id) desc,c_id asc;
45、檢索至少選修兩門課程的學生學號:
select s#
from sc
group by s#
having count(*)>=2;
46、查詢全部學生選修的課程和課程號和課程名:
select c# ,cname
from course
where c# in (select c# from sc group by c#);
47、查詢沒學過”葉平”老師講授的任一門課程的學生姓名:
select sname
from student
where s# not in (select s# from course,teacher,sc where course.t#=teacher.t# and sc.c#=course.c#
and tname='葉平');
select distinct t3.s_id,t3.sname from student t3,sc t4 where t3.s_id=t4.s_id and t4.c_id
not in(select t1.c_id from course t1,teacher t2 where t1.t_id=t2.t_id and t2.tname='葉平');
注:此題集合的思想,1、學過葉平的課的學生;2、葉平教過的課 取相反數
48、查詢兩門以上不及格課程的同學的學號以及其平均成績:
select s#,avg(isnull(score,0))
from sc
where s# in (select s# from sc where score<60 group by s# having count(*)>2)
group by s#;
select s_id,avg(score) from sc group by s_id
having count(distinct case when score < 60 then c_id end)>2
49、檢索“004”課程分數小於60,按分數降序排列的同學學號:
select s#
from sc
where c#='004'
and score<60
order by score desc;
50、刪除“002”同學的“001”課程的成績:
delect from sc
where s#='002'
and c#='001';