1. 程式人生 > >第四模塊MySQL50題作業,以及由作業引申出來的一些高端玩法

第四模塊MySQL50題作業,以及由作業引申出來的一些高端玩法

and order 歧義 weight class a when 沒有 2個 span

一、表關系

先創建如下表,並創建相關約束

1. 班級表class

create table class
    (
    cid int primary key auto_increment,
    caption char(10),
    grade_id int
    );
insert into class values
(1,少一一班,1),
(2,少二一班,2),
(3,少三二班,3),
(4,少四一班,4),
(5,少五三班,5);

2. 學生表student

create table student
    (
    sid int primary
key auto_increment, sname char(10), gender enum(,) not null, class_id int );
insert into student values
(1,喬丹,,1),
(2,艾弗森,,1),
(3,科比,,2),
(4,葫蘆娃,,3),
(5,張三豐,,5),
(6,洞房不敗,,4),
(7,櫻木花道,,2),
(8,松島菜菜子,,3),
(9,洞房不敗,,5);

3. 老師表teacher

create table teacher
    (
    tid int primary key auto_increment,
    tname char(10)
    );

一、表關系請創建如下表,並創建相關約束1. 班級表class【創建表語句】create table class(cid int primary key auto_increment,caption char(10),grade_id int);
【插入記錄語句】insert into class values(1,‘少一一班‘,1),(2,‘少二一班‘,2),(3,‘少三二班‘,3),(4,‘少四一班‘,4),(5,‘少五三班‘,5);
2. 學生表student【創建表語句】create table student(sid int primary key auto_increment,sname char(10),gender enum(‘男‘,‘女‘) not null,class_id int);
【插入記錄語句】insert into student values(1,‘喬丹‘,‘女‘,1),(2,‘艾弗森‘,‘女‘,1),(3,‘科比‘,‘男‘,2),(4,‘葫蘆娃‘,‘男‘,3),(5,‘張三豐‘,‘男‘,5),(6,‘洞房不敗‘,‘男‘,4),(7,‘櫻木花道‘,‘男‘,2),(8,‘松島菜菜子‘,‘女‘,3),(9,‘洞房不敗‘,‘女‘,5);
3. 老師表teacher【創建表語句】create table teacher(tid int primary key auto_increment,tname char(10));
【插入記錄語句】Insert into teacher values(1,‘張三‘),(2,‘李四‘),(3,‘王五‘),(4,‘蕭峰‘),(5,‘一休哥‘),(6,‘諸葛‘),(7,‘李四‘);
4. 課程表course【創建表語句】create table course(cid int primary key auto_increment,cname char(10),teacher_id int);
【插入記錄語句】insert into course values(1,‘生物‘,1),(2,‘體育‘,1),(3,‘物理‘,2),(4,‘數學‘,3),(5,‘語文‘,4),(6,‘英語‘,2),(7,‘土遁?沙地送葬‘,5),(8,‘夏日餵蚊子大法‘,3),(9,‘麻將牌九撲克千術‘,6);
5. 成績表score【創建表語句】create table score(sid int primary key auto_increment,student_id int,course_id int,score int);
【插入記錄語句】insert score values(1,1,1,60),(2,1,2,21),(3,2,2,99),(4,3,3,56),(5,4,1,56),(6,5,3,94),(7,5,4,40),(8,6,4,80),(9,7,3,37),(10,8,5,100),(11,8,6,89),(12,8,7,0),(13,3,8,45),(14,7,1,89),(15,2,7,89),(16,2,1,61);
6. 年級表class_grade【創建表語句】create table class_grade(gid int primary key auto_increment,gname char(10));
【插入記錄語句】insert class_grade values(1,‘一年級‘),(2,‘二年級‘),(3,‘三年級‘),(4,‘四年級‘),(5,‘五年級‘);
7. 班級任職表teach2cls【創建表語句】create table teach2cls(tcid int primary key auto_increment,tid int,cid int);
【插入記錄語句】insert into teach2cls values(1,1,1),(2,1,2),(3,2,1),(4,3,2),(5,4,5),(6,5,3),(7,5,5),(8,6,2),(9,6,4),(10,6,3),(11,4,1),(12,1,4);
二、操作表★註:由於樣本數量有限,為了能夠得到足夠的查詢結果,所有題目中涉及到“超過”或“以上”字樣的,均默認為包含該值(例如:查詢教授課程超過2門的老師的id和姓名,視作教授課程數>=2)
1、自行創建測試數據;(創建語句見"一、表關系")
2、查詢學生總人數;select count(*) as 學生總人數 from student;
3、查詢“生物”課程和“物理”課程成績都及格的學生id和姓名;【查法1——子查詢】select sid, snamefrom student where sid in(select student_idfrom scorewhere student_id in(select student_idfrom scorewhere course_id = (select cid from course where cname = ‘生物‘) and score >= 60)and course_id = (select cid from course where cname = ‘物理‘) and score >= 60);
【查法2——聯表】select sid, sname from studentwhere sid in (select t1.student_id from (select student_id from scorewhere course_id = (select cid from course where cname = ‘生物‘) and score >= 60) as t1inner join (select student_id from score where course_id = (select cid from course where cname = ‘物理‘) and score >= 60) as t2on t1.student_id=t2.student_id);
4、查詢每個年級的班級數,取出班級數最多的前三個年級select class.grade_id, class_grade.gname, count(class.cid) as 班級數from class inner join class_grade on class.grade_id=class_grade.gidgroup by class.grade_idorder by count(class.cid) desclimit 3;
5、查詢平均成績最高和最低的學生的id和姓名以及平均成績select stu.sid, stu.sname, avg(score) as 平均成績from student as stu inner join score as scoon stu.sid = sco.student_idgroup by stu.sidhaving avg(score) = (select avg(score) from score group by student_idorder by avg(score) desclimit 1) or avg(score) = (select avg(score) from score group by student_idorder by avg(score) asclimit 1);
6、查詢每個年級的學生人數;select t1.gname, count(s.sid) as 學生人數from (select * from class as c inner join class_grade as g on c.grade_id = g.gid) as t1inner join student as s on t1.cid = s.class_idgroup by t1.gid;
7、查詢每位學生的學號,姓名,選課數,平均成績;select stu.sid as 學號,stu.sname as 姓名,count(sco.course_id) as 選課數,avg(sco.score) as 平均成績from student as stu left join score as sco on stu.sid = sco.student_idgroup by sco.student_id;
8、查詢學生編號為“2”的學生的姓名、該學生成績最高的課程名、成績最低的課程名及分數;select t1.sname as 姓名,t2.cname as 課程名,t1.score as 分數from (select stu.sid, stu.sname, sco.course_id, sco.score from student as stu inner join score as sco on stu.sid = sco.student_id where stu.sid=2) as t1inner joincourse as t2 on t1.course_id = t2.cidgroup by t2.cidhaving score in (max(score),min(score));
9、查詢姓“李”的老師的個數和所帶班級數;select count(te.tid) as 姓李老師個數,count(tc.cid) as 所帶班級數from teacher as te inner join teach2cls as tcon te.tid = tc.tidwhere te.tname regexp "^李.*"group by te.tid;
10、查詢班級數小於5的年級id和年級名;select c.grade_id as 年級id,g.gname as 年級名from class as c inner join class_grade as gon c.grade_id = g.gidgroup by c.grade_idhaving count(c.cid)<5;
11、查詢班級信息,包括班級id、班級名稱、年級、年級級別(12為低年級,34為中年級,56為高年級),示例結果如下;select cid as 班級id,caption as 班級名稱,gname as 年級,casewhen g.gid in (1,2) then ‘低年級‘when g.gid in (3,4) then ‘中年級‘when g.gid in (5,6) then ‘高年級‘else ‘其他‘ end as 年級級別from class as c inner join class_grade as gon c.grade_id = g.gid;
12、查詢學過“張三”老師2門課以上的同學的學號、姓名;select stu.sid as 學號,stu.sname as 姓名from student as stu inner join score as sco on stu.sid = sco.student_idwhere sco.course_id in (select c.cidfrom teacher as t inner join course as con t.tid = c.teacher_idwhere t.tname = ‘張三‘)group by stu.sidhaving count(sco.course_id) >= 2;
13、查詢教授課程超過2門的老師的id和姓名;selecttid as id,tname as 姓名from teacher as t inner join course as c on t.tid = c.teacher_idgroup by c.teacher_idhaving count(c.cid) >= 2;
14、查詢學過編號“1”課程和編號“2”課程的同學的學號、姓名;select sid as 學號,sname as 姓名from studentwhere sid in (select student_id from scorewhere student_id in (select student_id from scorewhere course_id = 1)and course_id = 2);
15、查詢沒有帶過高年級的老師id和姓名;select tid as 老師id,tname as 姓名from teacherwhere tid not in (select tc.tidfrom class as c inner join teach2cls as tc on c.cid = tc.cidwhere c.grade_id in (5,6));
16、查詢學過“張三”老師所教的所有課的同學的學號、姓名;select distinctstu.sid as 學號,stu.sname as 姓名from student as stu inner join score as sco on stu.sid = sco.student_idwhere sco.course_id in (select c.cid from teacher as t inner join course as c on t.tid = c.teacher_idwhere t.tname = "張三");
17、查詢帶過超過2個班級的老師的id和姓名;select tid as id,tname as 姓名from teacherwhere tid in (select tid from teach2clsgroup by tidhaving count(cid) >= 2);
18、查詢課程編號“2”的成績比課程編號“1”課程低的所有同學的學號、姓名;select sid as 學號,sname as 姓名from studentwhere sid in(select t1.student_idfrom (select * from scorewhere course_id = 1) as t1inner join (select * from score where course_id = 2) as t2on t1.student_id = t2.student_idwhere t1.score > t2.score);
19、查詢所帶班級數最多的老師id和姓名;select tid as id,tname as 姓名from teacher where tid in (select tidfrom teach2clsgroup by tidhaving count(cid) = (select count(cid)from teach2clsgroup by tidorder by count(cid) desclimit 1));
20、查詢有課程成績小於60分的同學的學號、姓名;select sid as 學號,sname as 姓名from studentwhere sid in (select student_idfrom score where score < 60);
21、查詢沒有學全所有課的同學的學號、姓名;select sid as 學號,sname as 姓名from studentwhere sid in (select student_idfrom scoregroup by student_idhaving count(course_id) != (select count(cid) from course));
22、查詢至少有一門課與學號為“1”的同學所學相同的同學的學號和姓名;select sid as 學號,sname as 姓名from studentwhere sid in (select student_idfrom scorewhere course_id in (select course_id from scorewhere student_id = 1));
23、查詢至少學過學號為“1”同學所選課程中任意一門課的其他同學學號和姓名;select sid as 學號,sname as 姓名from studentwhere sid in (select student_idfrom scorewhere course_id in (select course_id from scorewhere student_id = 1) and student_id != 1);
24、查詢和“2”號同學學習的課程完全相同的其他同學的學號和姓名;select sid as 學號,sname as 姓名from studentwhere sid in (select student_idfrom scorewhere student_id != 2group by student_idhaving group_concat(course_id order by course_id asc) = (select group_concat(course_id order by course_id asc)from scorewhere student_id = 2group by student_id));
25、刪除學習“張三”老師課的score表記錄;delete from scorewhere course_id in (select c.cid from teacher as t inner join course as con t.tid = c.teacher_idwhere t.tname = ‘張三‘);
26、向score表中插入一些記錄,這些記錄要求符合以下條件:①沒有上過編號“2”課程的同學學號;②插入“2”號課程的平均成績;【插入第一條】insert into score(student_id, course_id, score) values((select sidfrom studentwhere sid not in(select s.student_idfrom score as swhere s.course_id = 2)order by sid desclimit 0,1),2,(select avg(s.score)from score as swhere s.course_id = 2));【插入第二條】insert into score(student_id, course_id, score) values((select sidfrom studentwhere sid not in(select s.student_idfrom score as swhere s.course_id = 2)order by sid desclimit 1,1),2,(select avg(s.score)from score as swhere s.course_id = 2));
【改limit後的第一個參數值,可繼續插入第三、四、...條】
27、按平均成績從低到高顯示所有學生的“語文”、“數學”、“英語”三門的課程成績,按如下形式顯示: 學生ID,語文,數學,英語,有效課程數,有效平均分;【這裏題目有歧義:有效課程數和有效平均分是僅以這3門課來統計,還是以學生所有科目來統計】【解一:僅以這3門課來統計】select t2.sid as 學生ID, sum(case when t1.cname = ‘語文‘ then t1.score else null end) as 語文,sum(case when t1.cname = ‘數學‘ then t1.score else null end) as 數學,sum(case when t1.cname = ‘英語‘ then t1.score else null end) as 英語,count(case when t1.cname in (‘語文‘,‘數學‘,‘英語‘) then 1 else null end) as 有效課程數,avg(case when t1.cname in (‘語文‘,‘數學‘,‘英語‘) then t1.score else null end) as 有效平均分from (select * from score as s inner join course as con s.course_id = c.cid) as t1right join student as t2on t1.student_id = t2.sidgroup by t2.sidorder by avg(case when t1.cname in (‘語文‘,‘數學‘,‘英語‘) then t1.score else null end) asc;
【解二:以該學生所有科目來統計】select t2.sid as 學生ID, sum(case when t1.cname = ‘語文‘ then t1.score else null end) as 語文,sum(case when t1.cname = ‘數學‘ then t1.score else null end) as 數學,sum(case when t1.cname = ‘英語‘ then t1.score else null end) as 英語,count(t1.score) as 有效課程數,avg(t1.score) as 有效平均分from (select * from score as s inner join course as con s.course_id = c.cid) as t1right join student as t2on t1.student_id = t2.sidgroup by t2.sidorder by avg(t1.score) asc;
28、查詢各科成績最高和最低的分:以如下形式顯示:課程ID,最高分,最低分;select course_id as 課程ID,max(score) as 最高分,min(score) as 最低分from scoregroup by course_id;
29、按各科平均成績從低到高和及格率的百分數從高到低順序;【這裏優先按平均成績從低到高排序,若遇到平均成績相同的則按及格率百分數從高到低排序】select course_id as 課程ID,avg(score) as 平均成績,concat(100*count(case when score>=60 then 1 else null end)/count(score),"%") as 及格率from scoregroup by course_idorder by avg(score) asc, count(case when score>=60 then 1 else null end)/count(score) desc;
30、課程平均分從高到低顯示(顯示任課老師);select t1.cname as 課程名稱,avg(t2.score) as 平均分,t1.tname as 任課老師from (select * from teacher as t inner join course as con t.tid = c.teacher_id) as t1 inner join score as t2on t1.cid = t2.course_idgroup by t2.course_idorder by avg(t2.score) desc;
31、查詢各科成績前三名的記錄(不考慮成績並列情況)【本題與44題類似,不會做,於是百度了下"如何在mysql中查詢每個分組的前幾名",參照其中的一個方法,寫出了答案】【註:這裏仍然是按照score表默認的排序,即sid的排序】select*from scorewhere(selectcount(*)from score as swheres.course_id = score.course_idands.score <= score.score)<= 3;
32、查詢每門課程被選修的學生數;select cname as 課程名,count(s.student_id) as 選修學生數from course as c left join score as s on c.cid = s.course_idgroup by c.cid;
33、查詢選修了2門以上課程的全部學生的學號和姓名;select sid as 學號,sname as 姓名from studentwhere sid in (select student_id from scoregroup by student_idhaving count(course_id) >= 2);
34、查詢男生、女生的人數,按倒序排列;select gender, count(sid)from studentgroup by genderorder by count(sid) desc;
35、查詢姓“張”的學生名單;【查法1——正則】select sname from studentwhere sname regexp "^張.*";
【查法2——like】select snamefrom studentwhere sname like "張%";
36、查詢同名同姓學生名單,並統計同名人數;select sname as 姓名,count(sid) as 同名人數 from studentgroup by snamehaving count(sid) > 1;
37、查詢每門課程的平均成績,結果按平均成績升序排列,平均成績相同時,按課程號降序排列;select avg(score),course_idfrom scoregroup by course_idorder by avg(score) asc, course_id desc;
38、查詢課程名稱為“數學”,且分數低於60的學生姓名和分數;select stu.sname as 學生姓名,sco.score as 分數from student as stu inner join score as scoon stu.sid = sco.student_idwhere sco.course_id = (select cid from course where cname = ‘數學‘)and sco.score < 60;
39、查詢課程編號為“3”且課程成績在80分以上的學生的學號和姓名;select sid as 學號,sname as 姓名from studentwhere sid in (select student_id from scorewhere course_id = 3 and score >= 80);
40、求選修了課程的學生人數select count(1) as 學生人數from(select distinct student_idfrom score) as t1;
41、查詢選修“王五”老師所授課程的學生中,成績最高和最低的學生姓名及其成績;select stu.sname as 學生姓名,sco.score as 成績from student as stu inner join score as scoon stu.sid = sco.student_idwhere score in ((select max(score)from scorewhere course_id in (select c.cidfrom teacher as t inner join course as con t.tid = c.teacher_id where t.tname = ‘王五‘)), (select min(score)from scorewhere course_id in (select c.cidfrom teacher as t inner join course as con t.tid = c.teacher_id where t.tname = ‘王五‘)));
42、查詢各個課程及相應的選修人數;select cname as 課程名,count(s.student_id) as 選修學生數from course as c left join score as s on c.cid = s.course_idgroup by c.cid;
43、查詢不同課程但成績相同的學生的學號、課程號、學生成績;select student_id as 學號,course_id as 課程號,score as 學生成績from scoregroup by scorehaving count(student_id) > 1;
44、查詢每門課程成績最好的前兩名學生id和姓名;【註:這裏指定了前兩名,所以若出現多名同分的學生也只取倒序排的默認前2名】【與31題類似…不會寫,於是百度了下"如何在mysql中查詢每個分組的前幾名",參照其中一種比較高端且高效的自定義變量的方法,寫出了答案】
set @num := 0, @cname := ‘‘;selectt2.cid as 課程ID,t2.cname as 課程名,t1.sid as 學生ID,t1.sname as 學生名,t1.score as 成績,@num := if(@cname = t2.cname, @num + 1, 1) as 排名,@cname := t2.cname as 課程名確認from (select stu.sid, stu.sname, sco.course_id, sco.score from student as stu inner join score as scoon stu.sid = sco.student_id) as t1right joincourse as t2on t1.course_id = t2.cidgroup byt2.cid, t1.score, t1.snamehaving排名 <= 2;

45、檢索至少選修兩門課程的學生學號;select sid as 學號from studentwhere sid in (select student_id from scoregroup by student_idhaving count(course_id) >= 2);
46、查詢沒有學生選修的課程的課程號和課程名;select cid as 課程號,cname as 課程名from coursewhere cid not in (select distinct course_idfrom score);
47、查詢沒帶過任何班級的老師id和姓名;selecttid as 老師id,tname as 姓名from teacherwhere tid not in (select distinct tidfrom teach2cls);
48、查詢有兩門以上課程超過80分的學生id及其平均成績;select student_id as 學生id,avg(score) as 平均成績from scorewhere student_id in (select student_idfrom scorewhere score >= 80group by student_idhaving count(course_id) >= 2)group by student_id;
49、檢索“3”課程分數小於60,按分數降序排列的同學學號;select distinctstudent_id as 學號from scorewhere course_id = 3 and score < 60order by score desc;
50、刪除編號為“2”的同學的“1”課程的成績;delete from scorewhere student_id = 2 and course_id = 1;
51、查詢同時選修了物理課和生物課的學生id和姓名;select sid as 學生id,sname as 姓名from studentwhere sid in (select student_idfrom scorewhere course_id = (select cid from course where cname = ‘生物‘))and sid in (select student_idfrom scorewhere course_id = (select cid from course where cname = ‘物理‘));

第四模塊MySQL50題作業,以及由作業引申出來的一些高端玩法