1、自行创建测试数据
create table class(
cid int not null auto_increment primary key,
caption char(4))engine=innodb auto_increment=1 default charset=utf8;
create table student(
sid int not null auto_increment primary key,
sname varchar(5),
gender char(1),
class_id int,
constraint fk_student_class foreign key(class_id) references class(cid)
)engine=innodb auto_increment=1 default charset=utf8;
create table teacher(
tid int not null auto_increment primary key,
tname varchar(5))engine=innodb auto_increment=1 default charset=utf8;
create table course(
cid int not null auto_increment primary key,
cname varchar(5),
teacher_id int,
constraint fk_course_teacher foreign key(teacher_id) references teacher(tid)
)engine=innodb auto_increment=1 default charset=utf8;
create table score(
sid int not null auto_increment primary key,
student_id int,
course_id int,
number int,
constraint fk_score_student foreign key(student_id) references student(sid),
constraint fk_score_course foreign key(course_id) references course(cid)
)engine=innodb auto_increment=1 default charset=utf8;
insert into class(caption) values('高一2班'),('高二1班'),('高二2班'),('高三1班'),('高三2班'),('高三3班');
insert into student(sname,gender,class_id) values('张一','男',1),('张二','女',2),('张三','男',3),('张四','女',4),('张五','男',5),('张六','女',6),('张七','男',7);
insert into teacher(tname) values('叶平'),('李晴'),('张玲');
insert into course(cname,teacher_id) values('语文',1),('数学',1),('英语',2),('政治',3);
insert into score(student_id,course_id,number) values(1,1,50),(1,2,61),(1,3,70),(1,4,80),(2,1,50),(2,2,82),(1,3,90),(1,4,57),(3,1,5),(3,2,88),(3,3,90),(4,1,100),(4,2,83),(4,3,66),(4,4,57),(5,1,67),(6,1,72),(6,2,61),(6,3,66);
2、查询“语文”课程比“数学”课程成绩高的所有学生的学号;
把生物和物理的分数查询分别拿出来,再重新放入到另一个查询的指定映射里,就可以实现不同科目在不同的列里
方法一:(连表)
select chinese.student_id,chinese.cname,chinese.number,math.cname,math.number from
(select student_id,cname,number from score
left join course on score.course_id=course.cid
where cname="语文") as chinese
left join
(select student_id,cname,number from score
left join course on score.course_id=course.cid
where cname="数学") as math
on chinese.student_id=math.student_id
where chinese.number>math.number;
方法二:(把数学分数表放入到指定映射中去,与21题、35题的思路一样)
select student_id,chinese,math from
(
select
s1.student_id,
s1.number as chinese,
(select number from score as s2 where course_id=2 and s2.student_id=s1.student_id) as math
from score as s1
where s1.course_id=1) as T
where chinese>math
9、查询课程编号“002”的成绩比课程编号“001”课程低的所有同学的学号、姓名;
方法一:连表操作(先分别找出02与01课程的成绩,再进行连表,使得02与01在不同的列,然后条件比较查询)
select s1.student_id,s1.course_id,s1.number as c1,s2.number as c2 from
(select * from score where course_id=1) as s1
left join (select * from score where course_id=2) as s2
on s1.student_id=s2.student_id
where s1.number>s2.number
方法二:子查询放入指定映射中
select student_id,course_id,c1,c2 from
(
select
s1.student_id,
s1.course_id,
s1.number as c1,
(select s2.number from score as s2 where s2.course_id=2 and s2.student_id=s1.student_id) as c2
from score as s1 where course_id=1) as T
where c1>c2
17、按平均成绩从低到高显示所有学生的“语文”、“数学”、“英语”三门的课程成绩,
按如下形式显示: 学生ID,语文,数学,英语,有效课程数,有效平均分;
select chinese.student_id,chinese_number,math_number,english_number,select_count,avg_cme from
(select student_id,number as chinese_number from score
left join course on score.course_id=course.cid
where cname="语文") as chinese
left join (select student_id,number as math_number from score
left join course on score.course_id=course.cid
where cname="数学") as math on chinese.student_id=math.student_id
left join (select student_id,cname,number as english_number from score
left join course on score.course_id=course.cid
where cname="英语") as english on chinese.student_id=english.student_id
left join (select student_id,count(1) as select_count,avg(number) as avg_cme from score
left join course on score.course_id=course.cid
where cname in ("语文","数学","英语")
group by student_id) as ag on chinese.student_id=ag.student_id
group by student_id
order by avg_cme asc;
21、查询各科成绩前三名的记录:(不考虑成绩并列情况) (排序+取前几个数据,临时表做指定映射,字段在与映射做比较)
求出所有成绩第三名的分数,score的分数与第三名的分数做比较,筛选记录
#select number from score where course_id=1
#group by number 同分的去重合并
#order by number desc limit 4,1; 倒序排并且取第五名
select * from
(
select
t2.student_id,
t2.course_id,
t2.number,
(select t1.number from score as t1
where t1.course_id = t2.course_id
group by t1.number
order by t1.number desc
limit 2,1) as no3
from score as t2
)as T
where T.number>=T.no3
order by course_id asc,number desc
23、查询出只选修了一门课程的全部学生的学号和姓名;
select student_id,count(1) from score group by student_id having count(1)=1;
26、查询同名同姓学生名单,并统计同名人数;
select s1.sname,count(1)/2 as same_name_quantity from student as s1,student as s2
where s1.sid != s2.sid and s1.sname=s2.sname;
select * from (select sname,count(1)as name_quantity from student group by sname) as s1
where s1.name_quantity>1; #正确写法
#where count(1)>1; 错误写法
#mysql报错:invaild use of group function;
#程序误以为在where后的count(1)是函数名,实际上在这里是字段名,所以会报错;
27、查询每门课程的平均成绩,结果按平均成绩升序排列,平均成绩相同时,按课程号降序排列;(双重排序)
select avg(if(isnull(number),0,number))as avg from score
group by course_id
order by avg(if(isnull(number),0,number)) asc,
course_id desc;
31、求选了课程的学生人数
select count(1) as student_quantity from(
select student_id from score group by student_id
) as s1;
34、查询不同课程但成绩相同的学生的学号、课程号、学生成绩;
select * from score as t1,score as t2
where t1.sid != t2.sid
and t1.course_id != t2.course_id
and t1.number = t2.number;
35、查询每门课程成绩最好的前两名;
select student_id,course_id,number from
(
select
t2.student_id,
t2.course_id,
t2.number,
(select t1.number from score as t1
where t1.course_id = t2.course_id
group by t1.number
order by t1.number desc
limit 1,1) as no2
from score as t2
) as T
where number>=no2
order by course_id asc,number desc
**************12-14题为一类题目
12、查询至少有一门课与学号为“006”的同学所学相同的同学的学号和姓名;
#select course_id from score where student_id=6;
select student_id,sname from score
left join student on score.student_id=student.sid
where course_id in (select course_id from score where student_id=6)
and
student_id != 6
group by student_id;
13、查询至少学过学号为“006”的同学所修课程的同学和姓名;(所修课程数量可能和006一样 或者 比006多且包含006所修课程)
#select course_id from score where student_id=6;
#select count(1) from score where student_id=6;
select student_id,sname,count(1) from score
left join student on score.student_id=student.sid
where course_id in (select course_id from score where student_id=6)
and
student_id != 6
group by student_id
having count(1)= (select count(1) from score where student_id=6)
14、查询和“006”号的同学学习的课程完全相同的其他同学学号和姓名;
思路:先查询006的所修课程数,然后找到相同课程数的人,再进行in(符合要求的课程数),对学生分组,最后找课程数符合要求的。
#6号的课程数和课程
#select count(1) from score where student_id=6;
#select course_id from score where student_id=6;
#找出和6号修课数目一样的学生号
#select student_id,course_id from score
#where student_id != 6
#group by student_id
#having count(1) = (select count(1) from score where student_id=6)
#找出和6号修课数目一样的学生号和课程号
#select student_id,course_id from score where student_id in(
#select student_id from score
#where student_id != 6
#group by student_id
#having count(1) = (select count(1) from score where student_id=6)
)
#在(与6号修课数目一样的学生号和课程号)里面in6号课程且count(1)=6号课程数
select tt.student_id,student.sname from (select student_id,course_id from score where student_id in(
select student_id from score
where student_id != 6
group by student_id
having count(1) = (select count(1) from score where student_id=6)
)) as tt
left join student on tt.student_id=student.sid
where tt.course_id in (select course_id from score where student_id=6)
group by tt.student_id
having count(1)= (select count(1) from score where student_id=6);