mysql练习题1-41

Mysql练习:

联表查询:

select score.sid,student.sid from score

left join student on score.student_id=student.sid

left join course on score.course_id=course.cid

left join class on student.class_id=class.cid

left join teacher on teacher.tid=course.teacher_id;

一、请创建如下表,并创建相关约束

# 数据库 use work;

# 班级表

create table class(

cid int auto_increment primary key,

caption varchar(30) not null

)engine=innodb default charset=utf8;

# 学生表,关联班级表 cid

create table student(

sid int auto_increment primary key,

sname varchar(30) not null,

gender varchar(4) not null default “男”,

class_id int not null,

constraint fk_class_stu foreign key (class_id ) references class(cid)

)engine=innodb default charset=utf8;

# 老师表

create table teacher(

tid int auto_increment primary key,

tname varchar(30) not null

)engine=innodb default charset=utf8;

# 课程表,关联 老师表 tid

create table course(

cid int auto_increment primary key,

cname varchar(30) not null,

teacher_id int not null,

constraint fk_course_teac foreign key (teacher_id) references teacher(tid)

)engine=innodb default charset=utf8;

# 成绩表,关联student  sidcourse cid

create table score(

sid int auto_increment primary key,

student_id int not null,

course_id int not null,

number float not null,

constraint fk_score_stu foreign key (student_id) references student(sid),

constraint fk_score_cour foreign key (course_id) references course(cid)

)engine=innodb default charset=utf8;

二、操作表

1、自行创建测试数据

①查询每个学生所在的班级名称:

select * from student left join class on student.class_id=class.cid;

②查询每门课程的老师的姓名

select * from course left join teacher on course.teacher_id=teacher.tid;

③ 查询每个老师所教了多少门课程:

select teacher_id,count(cname) from course group by teacher_id;

④查询男生女生的个数:

select gender,count(*) from student group by gender;

⑤临时表:

select sid,number from (select * from score where number>90) as B;

select sid from (select sid,number from score where number>90) as B;

 

2、查询生物课程比物理课程成绩高的所有学生的学号;

# ①连接student和core表,分别 查询到学过生物的 as A、学过物理的as B

因为表只能横向对比

(SELECT score.student_id,score.course_id,score.number,course.cname FROM score LEFT JOIN course ON score.course_id=course.cid WHERE course.cname='物理') as A

# ②连接ABinner join),然后查询到A.number>B.number的学生id

SELECT A.student_id FROM

(SELECT score.student_id,score.course_id,score.number,course.cname FROM score LEFT JOIN course ON score.course_id=course.cid WHERE course.cname='物理') as A

INNER JOIN

(SELECT score.student_id,score.course_id,score.number,course.cname FROM score LEFT JOIN course ON score.course_id=course.cid WHERE course.cname='生物') as B

ON A.student_id=B.student_id

WHERE A.number>B.number;

3、查询平均成绩大于60分的同学的学号和平均成绩; 

    思路:

        根据学生分组,使用avg获取平均值,通过having对avg进行筛选

select student_id,avg(number) from score group by student_id having avg(number)>60;

扩展:查询平均成绩大于60分的同学的学号、姓名和平均成绩; 

SELECT student.sid,student.sname,B.aaa

from student

LEFT JOIN

(select student_id,avg(number) as aaa from score GROUP BY student_id HAVING avg(number)>60) as B

ON student.sid=B.student_id;

4、查询所有同学的学号、姓名、选课数、总成绩;

SELECT student.sid,student.sname,count(student.sid),sum(score.number) from score

LEFT JOIN student on score.student_id=student.sid

GROUP BY student.sid;

5、查询姓的老师的个数;

SELECT count(tid) FROM teacher WHERE tname LIKE '%' ;

6、查询没学过叶平老师课的同学的学号、姓名;

①从scorecourse表,找到李平老师所教的课程id

SELECT cid FROM teacher LEFT JOIN  course ON teacher.tid=course.teacher_id

WHERE teacher.tname=’李平老师'

②从score表筛选出 选过 李平 老师课程的 学生id,并分组去重

SELECT score.student_id FROM score WHERE score.course_id

IN (SELECT cid FROM teacher LEFT JOIN  course

ON teacher.tid=course.teacher_id

WHERE teacher.tname='’李平老师') GROUP BY student_id

③ 联合学生表,筛选出 没选过 叶平 老师课的学生id以及姓名

 

7、查询学过“001”并且也学过编号“002”课程的同学的学号、姓名;

score表 筛选学过 001 002 的学生,

②然后分组,count(course_id)>1的是同时学过这两门课的

③联合student表得到姓名

SELECT score.student_id,student.sname

 FROM score LEFT JOIN student on score.student_id=student.sid

WHERE course_id=7 or course_id=8

GROUP BY student_id HAVING count(course_id)>1

8查询学过叶平老师所教的所有课的同学的学号、姓名;

SELECT student.sid,student.sname FROM student WHERE student.sid IN

(SELECT score.student_id FROM score WHERE score.course_id

IN

(SELECT cid FROM teacher LEFT JOIN  course

ON teacher.tid=course.teacher_id

WHERE teacher.tname='张益老师') GROUP BY student_id)

9、查询课程编号“002”的成绩比课程编号“001”课程低的所有同学的学号、姓名;

# 学过001as AINNER JOIN,学过002as B

SELECT student.sid,student.sname FROM

(

SELECT A.student_id,A.course_id FROM

(SELECT * FROM score WHERE course_id=7) as A

INNER JOIN

(SELECT * FROM score WHERE course_id=8) as B

ON A.student_id=B.student_id

WHERE A.number<B.number) as C

LEFT JOIN student

ON  C.student_id=student.sid

10、查询有课程成绩小于60分的同学的学号、姓名;

# 先找到成绩<60的,如果遇到某一个同学有多门成绩<60的可以用group byDISTINCT(DISTINCT去重效率不高)

SELECT sid,sname FROM student WHERE sid IN

(SELECT DISTINCT student_id FROM score WHERE number<70)

#group去重

SELECT sid,sname FROM student WHERE sid IN

(SELECT student_id FROM score WHERE number<70 GROUP BY student_id)

11、查询没有学全所有课的同学的学号、姓名;

#①查询所学课程数量 小于课程总数的

SELECT student_id,count(1) FROM score GROUP BY student_id

HAVING count(1)<(SELECT COUNT(cid) FROM course);

#②找到姓名

SELECT sid,sname FROM student WHERE sid IN

(SELECT student_id FROM score GROUP BY student_id

HAVING count(1)<(SELECT COUNT(cid) FROM course));

12、查询至少有一门课与学号为“001”的同学所学相同的同学的学号和姓名;

# ①先查询到这位同学选的所有的课

SELECT student_id,course_id FROM score WHERE student_id=1;

# ②在score表中查到学习了这些课程的学生学号,并排除001自己

SELECT student_id FROM score WHERE student_id !=1 AND course_id IN

(SELECT course_id FROM score WHERE student_id=1) GROUP BY student_id);

# ③联表student拿到姓名

SELECT student.sid,student.sname FROM score LEFT JOIN student ON score.student_id=student.sid

WHERE student_id !=1 AND course_id IN

(SELECT course_id FROM score WHERE student_id=1) GROUP BY student_id;

13、查询至少学过学号为“001”同学所选课程中任意一门课的其他同学学号和姓名;

14、查询和“002”号的同学学习的课程完全相同的其他同学学号和姓名

15、删除学习“叶平”老师课的score表记录;

16、SC表中插入一些记录,这些记录要求符合以下条件:①没有上过编号“002”课程的同学学号;②插入“002”号课程的平均成绩; 

#插入score表的值是 查询的结果(其中平均成绩也是动态计算的)

INSERT INTO score(student_id,course_id,number)

SELECT student_id,2,(SELECT avg(number) FROM score WHERE course_id=2) FROM score WHERE course_id!=2;

17、按平均成绩从低到高显示所有学生的“语文”、“数学”、“英语”三门的课程成绩,按如下形式显示: 学生ID,语文,数学,英语,有效课程数,有效平均分;

SELECT

student_id as 学生ID,

(SELECT number FROM score as s2 WHERE s1.student_id=s2.student_id AND course_id=(SELECT cid FROM course WHERE course.cname='生物')) as 生物,

(SELECT number FROM score as s2 WHERE s1.student_id=s2.student_id AND course_id=(SELECT cid FROM course WHERE course.cname='Math')) as 数学,

(SELECT number FROM score as s2 WHERE s1.student_id=s2.student_id AND course_id=(SELECT cid FROM course WHERE course.cname='物理')) as 物理,

count(s1.course_id) as 有效课程数,

avg(s1.number) as 有效平均分

FROM score AS s1

GROUP BY student_id DESC;

18、查询各科成绩最高和最低的分:以如下形式显示:课程ID,最高分,最低分;

SELECT course_id,MAX(number),MIN(number) FROM score GROUP BY course_id;

扩展:当最低分<10时显示0,大于等于10时显示实际分数

SELECT course_id,max(number),case when min(number)<10 THEN 0 ELSE min(number) END as m FROM score GROUP BY course_id;

19、按各科平均成绩从低到高和及格率的百分数从高到低顺序;

SELECT course_id,avg(number),sum(1),sum(case when number<60 THEN 0 ELSE 1 END)/sum(1)  as jigel FROM score

GROUP BY course_id

ORDER BY avg(number) asc,jigel DESC;

20、课程平均分从高到低显示(显示任课老师);

SELECT score.course_id,course.cname,avg(number),teacher.tname FROM score

LEFT JOIN course ON score.course_id=course.cid

LEFT JOIN teacher ON teacher.tid=course.teacher_id

GROUP BY course_id ORDER BY avg(number) desc;

另外:防止分数里面有null就置为0,再做平均分

 select avg(if(isnull(score.num),0,score.num)),teacher.tname from course

21、查询各科成绩前三名的记录:(不考虑成绩并列情况

# 先查询到某一科课程的成绩(避免分数有相同的,用GROUP BY去重

SELECT number FROM score WHERE course_id=7 GROUP BY number ORDER BY number desc LIMIT 0,1;   #课程7第一名

SELECT number FROM score WHERE course_id=7 GROUP BY number ORDER BY number desc LIMIT 1,1;   #第二名

SELECT number FROM score WHERE course_id=7 GROUP BY number ORDER BY number desc LIMIT 2,1;   #第三名

# 大于第4名的成绩就是前3

SELECT * FROM

(

SELECT

student_id,course_id,number,

(SELECT number FROM score as s2 WHERE s2.course_id=s1.course_id GROUP BY  s2.number ORDER BY s2.number desc LIMIT 0,1),

(SELECT number FROM score as s2 WHERE s2.course_id=s1.course_id GROUP BY  s2.number ORDER BY s2.number desc LIMIT 3,1) as cc

FROM score as s1

) as B

WHERE B.number > B.cc

同:第35

22、查询每门课程被选修的学生数;

SELECT course_id,count(student_id) FROM score GROUP BY course_id;

扩展:查询热门课程(选修人数大于>5的)

SELECT course_id,count(1) FROM score GROUP BY course_id HAVING count(1)>5;

23、查询出只选修了一门课程的全部学生的学号和姓名;

#①查询到只学了一门课程的学生的id

SELECT student_id,count(1) FROM score GROUP BY student_id HAVING count(1)=1

#②联表

SELECT score.student_id,student.sname,count(1) FROM score

LEFT JOIN student ON score.student_id=student.sid

GROUP BY student_id HAVING count(1)=1;

24、查询男生、女生的人数;

SELECT gender,COUNT(1) FROM student GROUP BY gender;

25、查询姓“张”的学生名单;

SELECT * FROM student WHERE sname LIKE '%';

26、查询同名同姓学生名单,并统计同名人数;

SELECT sname,count(1) FROM student GROUP BY sname;

27、查询每门课程的平均成绩,结果按平均成绩升序排列,平均成绩相同时,按课程号降序排列;

SELECT course_id,avg(if(isnull(number),0,number)) as avg FROM score GROUP BY course_id

ORDER BY avg asc,course_id desc;

28、查询平均成绩大于85的所有学生的学号、姓名和平均成绩;

SELECT score.student_id,student.sname,avg(number) FROM score

LEFT JOIN student ON student.sid=score.student_id

GROUP BY score.student_id HAVING avg(number)>85;

29、查询课程名称为“数学”,且分数低于60的学生姓名和分数;

SELECT score.student_id,student.sname,course.cname,score.number FROM score

LEFT JOIN student ON student.sid=score.student_id

LEFT JOIN course ON score.course_id=course.cid

WHERE course.cname='生物' and score.number<60;

30、查询课程编号为003且课程成绩在80分以上的学生的学号和姓名; 

29题:

SELECT score.student_id,student.sname,course.cname,score.number FROM score

LEFT JOIN student ON student.sid=score.student_id

LEFT JOIN course ON score.course_id=course.cid

WHERE course.cid=7 and score.number>80;

31、求选了课程的学生人数

# group by

SELECT count(c) FROM

(SELECT count(course_id) as c FROM score GROUP BY student_id) as A;

# distinct

SELECT count(DISTINCT student_id) FROM score;

32、查询选修“杨艳”老师所授课程的学生中,成绩最高的学生姓名及其成绩;

#先找到“杨艳”老师所教课程的课程id

SELECT student.sid,student.sname,score.number FROM score

LEFT JOIN student ON student.sid=score.student_id

WHERE score.course_id IN

(select course.cid FROM teacher LEFT JOIN course

ON teacher.tid=course.teacher_id

WHERE teacher.tname='张益老师')

ORDER BY score.number DESC LIMIT 0,1;

33、查询各个课程及相应的选修人数;

SELECT course.cname,count(1) FROM score

LEFT JOIN course ON course.cid=score.course_id

GROUP BY course_id;

34、查询不同课程但成绩相同的学生的学号、课程号、学生成绩;

#SELECT * FROM  t1, t2;   结果有 t1的条数* t2的条数(笛卡尔积)

SELECT s1.student_id,s1.course_id,s1.number FROM score as s1,score s2

WHERE s1.sid != s2.sid AND s1.course_id != s2.course_id AND s1.number=s2.number;

35、查询每门课程成绩最好的前两名;

36、检索至少选修两门课程的学生学号;

SELECT student_id,count(student_id) FROM score

GROUP BY student_id

HAVING count(student_id)>1;

37、查询全部学生都选修的课程的课程号和课程名;

#score表按照course_id进行分组,每门课程的学生人数=学生的总人数

SELECT course_id,course.cname,count(1) FROM score

LEFT JOIN course ON course.cid=score.course_id

GROUP BY course_id

HAVING count(student_id)=(SELECT count(1) FROM student);

38、查询没学过“叶平”老师讲授的任一门课程的学生姓名;

#①先查询到“叶平”老师任课的课程id

#score表中查到学习了叶平老师课的所有学生id(不能直接NOT IN,否则不能完整排除)

#③从student表中找到没有被排除的学生

SELECT * FROM student WHERE student.sid NOT IN

(SELECT score.student_id FROM score WHERE score.course_id IN

(SELECT course.cid FROM course LEFT JOIN teacher ON teacher.tid=course.teacher_id

WHERE teacher.tname='张益老师'));

39、查询两门以上不及格课程的同学的学号及其平均成绩;

#先找到不及格的,再分组计算

SELECT student_id,avg(number) FROM score WHERE number<80 GROUP BY student_id HAVING count(1)>2;

40、检索004”课程分数小于60,按分数降序排列的同学学号;

SELECT * FROM score WHERE course_id=7 AND number<80 ORDER BY number DESC;

41、删除002”同学的“001”课程的成绩;

DELETE from score WHERE student_id=2 AND course_id=1;

原文地址:https://www.cnblogs.com/chenhongl/p/14421461.html