测试数据
- 学生表
Student(s_id,s_name,s_birth,s_sex) --学生编号,学生姓名, 出生年月,学生性别 - 课程表
Course(c_id,c_name,t_id) – --课程编号, 课程名称, 教师编号 - 教师表
Teacher(t_id,t_name) --教师编号,教师姓名 - 成绩表
Score(s_id,c_id,s_score) --学生编号,课程编号,分数
-- 建表
-- 学生表
CREATE TABLE `Student`(
`s_id` VARCHAR(20),
`s_name` VARCHAR(20) NOT NULL DEFAULT '',
`s_birth` VARCHAR(20) NOT NULL DEFAULT '',
`s_sex` VARCHAR(10) NOT NULL DEFAULT '',
PRIMARY KEY(`s_id`)
);
-- 课程表
CREATE TABLE `Course`(
`c_id` VARCHAR(20),
`c_name` VARCHAR(20) NOT NULL DEFAULT '',
`t_id` VARCHAR(20) NOT NULL,
PRIMARY KEY(`c_id`)
);
-- 教师表
CREATE TABLE `Teacher`(
`t_id` VARCHAR(20),
`t_name` VARCHAR(20) NOT NULL DEFAULT '',
PRIMARY KEY(`t_id`)
);
-- 成绩表
CREATE TABLE `Score`(
`s_id` VARCHAR(20),
`c_id` VARCHAR(20),
`s_score` INT(3),
PRIMARY KEY(`s_id`,`c_id`)
);
-- 插入学生表测试数据
insert into Student values('01' , '赵雷' , '1990-01-01' , '男');
insert into Student values('02' , '钱电' , '1990-12-21' , '男');
insert into Student values('03' , '孙风' , '1990-05-20' , '男');
insert into Student values('04' , '李云' , '1990-08-06' , '男');
insert into Student values('05' , '周梅' , '1991-12-01' , '女');
insert into Student values('06' , '吴兰' , '1992-03-01' , '女');
insert into Student values('07' , '郑竹' , '1989-07-01' , '女');
insert into Student values('08' , '王菊' , '1990-01-20' , '女');
-- 课程表测试数据
insert into Course values('01' , '语文' , '02');
insert into Course values('02' , '数学' , '01');
insert into Course values('03' , '英语' , '03');
-- 教师表测试数据
insert into Teacher values('01' , '张三');
insert into Teacher values('02' , '李四');
insert into Teacher values('03' , '王五');
-- 成绩表测试数据
insert into Score values('01' , '01' , 80);
insert into Score values('01' , '02' , 90);
insert into Score values('01' , '03' , 99);
insert into Score values('02' , '01' , 70);
insert into Score values('02' , '02' , 60);
insert into Score values('02' , '03' , 80);
insert into Score values('03' , '01' , 80);
insert into Score values('03' , '02' , 80);
insert into Score values('03' , '03' , 80);
insert into Score values('04' , '01' , 50);
insert into Score values('04' , '02' , 30);
insert into Score values('04' , '03' , 20);
insert into Score values('05' , '01' , 76);
insert into Score values('05' , '02' , 87);
insert into Score values('06' , '01' , 31);
insert into Score values('06' , '03' , 34);
insert into Score values('07' , '02' , 89);
insert into Score values('07' , '03' , 98);
sql语法注意事项
- 单引号和反引号区别
反引号作用于列字段,使用单引号表示是一个字符串
列属性也可以不用符号
- case when … then … else … end
条件select ,通常使用方式case when … then … else … end as 列别名
case when sc.s_score is null then 0 else 1 end as a
-
sql优化:(not) exists 代替 (not) in
ps:
-
group_concat( )聚合函数
-
select 分组后的属性里再使用select
-
查询xx率
-
排名,mysql没有rank函数 – 两张相同表连接,再比较大小,分组后计算比a大或者小的数量
-
日期相关函数
-
左外连接,有外连接
左外连接:左表全部都有,左右两表能不能匹配是看 on 条件的左右两边 ,而不是看表在sql语句中的前后顺序
常规题目
- 查询"01"课程比"02"课程成绩高的学生的信息及课程分数
-- 包括没有02课程分数的学生
select s.*,sc1.s_score as `01分数`,sc2.s_score as `02分数`
from student s
join score sc1 on s.s_id = sc1.s_id and sc1.c_id = '01'
left join score sc2 on s.s_id = sc2.s_id and sc2.c_id = '02'
where sc1.s_score > sc2.s_score or sc2.s_score is null
-- 不包括没有02课程分数的学生
select s.*,sc1.s_score as `01分数`,sc2.s_score as `02分数`
from student s
join score sc1 on s.s_id = sc1.s_id and sc1.c_id = '01'
join score sc2 on s.s_id = sc2.s_id and sc2.c_id = '02'
where sc1.s_score > sc2.s_score
- 查询"01"课程比"02"课程成绩低的学生的信息及课程分数
- 查询平均成绩大于等于60分的同学的学生编号和学生姓名和平均成绩
select st.s_id,st.s_name,avg(sc.s_score) as avg_score
from student st
join score sc on st.s_id = sc.s_id
group by st.s_id
having avg_score >= 60
avg(sc.s_score) 可以换成 round(avg(sc.s_score),2) 四舍五入
- 查询平均成绩小于60分的同学的学生编号和学生姓名和平均成绩(包括有成绩的和无成绩的)
select st.s_id,st.s_name,avg(sc.s_score) as `avg_score`
from student st
left join score sc on st.s_id = sc.s_id
group by st.s_id
having avg_score < 60 or avg_score is null
- 查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩
-- 用count函数
select st.s_id,st.s_name,count(sc.c_id),sum(sc.s_score)
from student st
left join score sc on st.s_id = sc.s_id
group by st.s_id
-- 用sum函数
select t.s_id,t.s_name,sum(a),sum(s_score)
from
(select st.*, (case when sc.s_score is null then 0 else 1 end)as a,sc.s_score
from student st
left join score sc on st.s_id = sc.s_id) t
group by t.s_id
- 查询"李"姓老师的数量
select count(1)
from teacher
where t_name like '李%'
- 查询学过"张三"老师授课的同学的信息
select distinct st.*
from student st
join score sc on st.s_id = sc.s_id
join course c on sc.c_id = c.c_id
join teacher t on c.t_id = t.t_id and t.t_name = '张三'
- 查询没学过"张三"老师授课的同学的信息
select *
from student st
where st.s_id not in (
select distinct sc.s_id
from course c
join teacher t on c.t_id = t.t_id and t.t_name = '张三'
join score sc on c.c_id = sc.c_id)
-- sql优化 exists代替in
select *
from student st
where not exists (
select 1
from course c
join teacher t on c.t_id = t.t_id and t.t_name = '张三'
join score sc on c.c_id = sc.c_id
where st.s_id = sc.s_id
)
- 查询学过编号为"01"并且也学过编号为"02"的课程的同学的信息
select st.*
from student st
join score sc1 on st.s_id = sc1.s_id and sc1.c_id = '01'
join score sc2 on st.s_id = sc2.s_id and sc2.c_id = '02'
select a.*
from student a,score b,score c
where a.s_id = b.s_id and a.s_id = c.s_id and b.c_id='01' and c.c_id='02';
- 查询学过编号为"01"但是没有学过编号为"02"的课程的同学的信息
-- 全用连接
select st.*
from student st
join score sc1 on st.s_id = sc1.s_id and sc1.c_id = '01'
left join score sc2 on st.s_id = sc2.s_id and sc2.c_id = '02'
where sc2.c_id is null
-- 子查询,但是有in
select a.*
from student a
where a.s_id in (select s_id from score where c_id='01' ) and a.s_id not in(select s_id from score where c_id='02')
-- 子查询,用exists
select a.*
from student a
where exists (select 1
from score s
where s.c_id ='01' and a.s_id = s.s_id)
and not exists (select 1
from score s
where s.c_id ='02' and a.s_id = s.s_id)
分析:
1.使用 JOIN 的第一个查询通常在处理大量数据时更有效,因为数据库可以更高效地执行连接操作。
2.使用子查询的第二个和第三个查询可能会较慢,尤其是当 student 表和 score 表很大时,因为对于每个学生记录,数据库都需要执行两次独立的子查询。
3.EXISTS 和 NOT EXISTS 通常比 IN 和 NOT IN 更高效,因为它们在找到第一个匹配的行后就会停止搜索。
- 查询没有学全所有课程的同学的信息
-- 直接查
select st.*
from student st
left join score sc on st.s_id = sc.s_id
group by st.s_id
having count(sc.s_id) < (select count(1) from course)
-- 先查学全的,再not in
select *
from student
where s_id not in(
select s_id from score t1
group by s_id having count(*) =(select count(distinct c_id) from course))
- 查询至少有一门课与学号为"01"的同学所学相同的同学的信息
select *
from student
where s_id in (select distinct(sc.s_id)
from score sc
where sc.c_id in (select c_id from score where s_id = '01'))
- 查询和"01"号的同学学习的课程完全相同的其他同学的信息
select *
from student
where s_id in(select distinct s_id
from(select s_id,group_concat(c_id order by c_id) as c_ids
from score
group by s_id) as a
where a.c_ids =(select group_concat(c_id order by c_id)
from score
where s_id = '01'
group by s_id))
and s_id <> '01'
SELECT
*
FROM
student
WHERE
s_id IN (
SELECT
s_id
FROM
score
WHERE
# 保证学习的课程相同
c_id IN (SELECT DISTINCT c_id FROM score WHERE s_id = '01')
AND s_id != '01'
GROUP BY
s_id
HAVING
# 保证学习的课程数量相同
count(c_id) = (select count(*) from score where s_id = '01')
)
- 查询没学过"张三"老师讲授的任一门课程的学生姓名(不是没学过张三老师课的学生)
select s_name
from student
where s_id not in ( #查询学过张三老师所有课的学生
select s_id
from score
where c_id in (select c_id
from teacher t
join course c on t.t_id = c.t_id
where t.t_name = '张三')
group by s_id
having count(c_id) = (select count(*)
from teacher t
join course c on t.t_id = c.t_id
where t.t_name = '张三'))
- 查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩
select st.s_id,st.s_name,avg(sc.s_score)
from student st
join score sc on st.s_id = sc.s_id
where st.s_id in (select s_id
from score
where s_score < 60
group by s_id
having count(1) >= 2)
group by st.s_id
select a.s_id,st.s_name,avg(a.s_score) as avg_score
from (select *, case when s_score < 60 then 1 else 0 end as num
from score) as a
join student st on a.s_id = st.s_id
group by a.s_id
having sum(a.num) >= 2
- 检索"01"课程分数小于60,按分数降序排列的学生信息
select st.*
from score sc
join student st on sc.s_id = st.s_id
where c_id = '01' and s_score < 60
order by sc.s_score desc
- 按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩
select sc.s_id,
st.s_name,
(select s_score from score where s_id = sc.s_id and c_id = '01')as 语文,
(select s_score from score where s_id = sc.s_id and c_id = '02')as 数学,
(select s_score from score where s_id = sc.s_id and c_id = '03')as 英语,
avg(sc.s_score)as avg_score
from score sc
join student st on sc.s_id = st.s_id
group by sc.s_id
order by avg_score desc
- 查询各科成绩最高分、最低分和平均分:以如下形式显示:课程ID,课程name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率。及格为>=60,中等为:70-80,优良为:80-90,优秀为:>=90
select c.c_id,
c.c_name,
max(s.s_score) as 最高分,
min(s.s_score) as 最低分,
avg(s.s_score) as 平均分,
(select count(1) from score where c_id = c.c_id and s_score >= 60)/count(s.s_score) as 及格率,
(select count(1) from score where c_id = c.c_id and s_score >=70 and s_score < 80)/count(s.s_score) as 中等率,
(select count(1) from score where c_id = c.c_id and s_score >=80 and s_score < 90)/count(s.s_score) as 优良率,
(select count(1) from score where c_id = c.c_id and s_score >=90)/count(s.s_score) as 优秀率
from course c
join score s on c.c_id = s.c_id
group by c.c_id
select c.c_id,
c.c_name,
max(s.s_score) as 最高分,
min(s.s_score) as 最低分,
avg(s.s_score) as 平均分,
sum(case when s.s_score >= 60 then 1 else 0 end)/sum(case when s.s_score then 1 else 0 end) as 及格率,
sum(case when a.s_score>=70 and a.s_score<80 then 1 else 0 end)/sum(case when s.s_score then 1 else 0 end) as 及格率,
sum(case when a.s_score>=80 and a.s_score<90 then 1 else 0 end)/sum(case when s.s_score then 1 else 0 end) as 及格率,
sum(case when a.s_score>=90 then 1 else 0 end)/sum(case when s.s_score then 1 else 0 end) as 及格率,
from course c
join score s on c.c_id = s.c_id
group by c.c_id
- 按各科成绩进行排序,并显示排名
select s2.c_id,s2.s_id,s2.s_score,count(s1.s_score)+1 as ranks
from score s1
right join score s2 on s1.c_id = s2.c_id and s1.s_score > s2.s_score
group by s2.s_id,s2.c_id
order by s2.c_id,ranks
- 查询学生的总成绩并进行排名
select t1.s_id,t1.sum_score,count(t2.s_id) +1 as ranks
from (select s_id,sum(s_score) as sum_score
from score
group by s_id) as t1
left join (select s_id,sum(s_score) as sum_score
from score
group by s_id) as t2 on t1.sum_score < t2.sum_score
group by t1.s_id
order by ranks
- 查询不同老师所教不同课程平均分从高到低显示
select t.t_id,t.t_name,c.c_id,c.c_name,avg(s.s_score) as avg_score
from teacher t
join course c on t.t_id = c.t_id
join score s on c.c_id = s.c_id
group by t.t_id,c.c_id
order by avg_score desc
- 查询所有课程的成绩第2名到第3名的学生信息及该课程成绩
select s1.c_id,st.*,count(distinct(s2.s_score)) +1 as ranks,s1.s_score
from score s1
left join score s2 on s1.c_id = s2.c_id and s1.s_score < s2.s_score
join student st on s1.s_id = st.s_id
group by s1.c_id,s1.s_id
having ranks >= 2 and ranks <= 3
order by s1.c_id,ranks
- 统计各科成绩各分数段人数:课程编号,课程名称,[100-85],[85-70],[70-60],[0-60]及所占百分比
select c.c_id,
c.c_name,
(select count(1) from score where c_id = c.c_id and s_score >= 85) as '[100-85]人数',
(select count(1) from score where c_id = c.c_id and s_score >= 70 and s_score <= 85) as '[100-85]人数',
(select count(1) from score where c_id = c.c_id and s_score >= 60 and s_score <= 70) as '[100-85]人数',
(select count(1) from score where c_id = c.c_id and s_score <= 60) as '[100-85]人数',
(select count(1) from score where c_id = c.c_id and s_score >= 85)/count(s.s_id) as '[100-85]百分比',
(select count(1) from score where c_id = c.c_id and s_score >= 70 and s_score <= 85)/count(s.s_id) as '[100-85]百分比',
(select count(1) from score where c_id = c.c_id and s_score >= 60 and s_score <= 70)/count(s.s_id) as '[100-85]百分比',
(select count(1) from score where c_id = c.c_id and s_score <= 60)/count(s.s_id) as '[100-85]百分比'
from course c
join score s on c.c_id = s.c_id
group by c.c_id
select distinct f.c_name,a.c_id,b.`85-100`,b.百分比,c.`70-85`,c.百分比,d.`60-70`,d.百分比,e.`0-60`,e.百分比
from score a
left join (select c_id,SUM(case when s_score >85 and s_score <=100 then 1 else 0 end) as `85-100`,
ROUND(100*(SUM(case when s_score >85 and s_score <=100 then 1 else 0 end)/count(*)),2) as 百分比
from score GROUP BY c_id)b on a.c_id=b.c_id
left join (select c_id,SUM(case when s_score >70 and s_score <=85 then 1 else 0 end) as `70-85`,
ROUND(100*(SUM(case when s_score >70 and s_score <=85 then 1 else 0 end)/count(*)),2) as 百分比
from score GROUP BY c_id)c on a.c_id=c.c_id
left join (select c_id,SUM(case when s_score >60 and s_score <=70 then 1 else 0 end) as `60-70`,
ROUND(100*(SUM(case when s_score >60 and s_score <=70 then 1 else 0 end)/count(*)),2) as 百分比
from score GROUP BY c_id)d on a.c_id=d.c_id
left join (select c_id,SUM(case when s_score >=0 and s_score <=60 then 1 else 0 end) as `0-60`,
ROUND(100*(SUM(case when s_score >=0 and s_score <=60 then 1 else 0 end)/count(*)),2) as 百分比
from score GROUP BY c_id)e on a.c_id=e.c_id
left join course f on a.c_id = f.c_id
- 查询学生平均成绩及其名次
select t1.s_id,t1.avg_score,count(t2.avg_score) +1 as ranks
from (select s_id,avg(s_score) as avg_score
from score
group by s_id) as t1
left join (select s_id,avg(s_score) as avg_score
from score
group by s_id) as t2 on t1.avg_score < t2.avg_score
group by t1.s_id
order by ranks
- 查询各科成绩前三名的记录
select s1.c_id,s1.s_id,s1.s_score,count(s2.s_score)+1 as ranks
from score s1
left join score s2 on s1.c_id = s2.c_id and s1.s_score < s2.s_score
group by s1.c_id,s1.s_id
having ranks <= 3
order by s1.c_id,ranks
- 查询每门课程被选修的学生数
select c_id,count(s_id)
from score
group by c_id
- 查询出只有两门课程的全部学生的学号和姓名
select st.*
from score sc
join student st on sc.s_id = st.s_id
group by sc.s_id
having count(sc.c_id) = 2
- 查询男生、女生人数
select s_sex,count(*)
from student
group by s_sex
- 查询名字中含有"风"字的学生信息
select *
from student
where s_name like '%风%'
- 查询相同姓名且相同性别的学生名单,并统计同名人数
select s_name,s_sex,count(s_id)
from student
group by s_name,s_sex
having count(s_id) > 1
select a.s_name,a.s_sex,count(*)
from student a
JOIN student b on a.s_id !=b.s_id and a.s_name = b.s_name and a.s_sex = b.s_sex
GROUP BY a.s_name,a.s_sex
- 查询1990年出生的学生名单
select *
from student
where s_birth like '1990%'
- 查询每门课程的平均成绩,结果按平均成绩降序排列,平均成绩相同时,按课程编号升序排列
select c_id,avg(s_score) as avg_score
from score
group by c_id
order by avg_score desc,c_id asc
- 查询平均成绩大于等于85的所有学生的学号、姓名和平均成绩
select st.s_id,st.s_name,avg(sc.s_score) as avg_score
from score sc
join student st on sc.s_id = st.s_id
group by sc.s_id
having avg_score >= 85
- 查询课程名称为"数学",且分数低于60的学生姓名和分数
select st.s_name,s.s_score
from score s
join course c on s.c_id = c.c_id
join student st on s.s_id = st.s_id
where c.c_name = '数学' and s.s_score < 60
- 查询所有学生的课程及分数情况
select st.s_id,
st.s_name,
(select s.s_score from score s join course c on s.c_id = c.c_id where s.s_id = st.s_id and c.c_name = '语文') as '语文',
(select s.s_score from score s join course c on s.c_id = c.c_id where s.s_id = st.s_id and c.c_name = '数学') as '数学',
(select s.s_score from score s join course c on s.c_id = c.c_id where s.s_id = st.s_id and c.c_name = '英语') as '英语'
from student st
left join score sc on st.s_id = sc.s_id
left join course c on sc.c_id = c.c_id
group by st.s_id
select st.s_id,st.s_name,c.c_id,c.c_name,sc.s_score
from student st
left join score sc on st.s_id = sc.s_id
join course c on sc.c_id = c.c_id
- 查询任何一门课程成绩在70分以上的姓名、课程名称和分数
select st.s_id,st.s_name,c.c_name,sc.s_score
from score sc
join student st on sc.s_id = st.s_id
join course c on sc.c_id = c.c_id
where sc.s_score >= 70
- 查询不及格的课程
select st.s_id,st.s_name,c.c_name,sc.s_score
from score sc
join student st on sc.s_id = st.s_id
join course c on sc.c_id = c.c_id
where sc.s_score < 60
- 查询课程编号为01且课程成绩在70分以上的学生的学号和姓名
select st.s_id,st.s_name,sc.s_score
from score sc
join student st on sc.s_id = st.s_id
where sc.c_id = '01' and sc.s_score > 70
- 求每门课程的学生人数
select c_id,count(s_id)
from score
group by c_id
- 查询选修"张三"老师所授课程的学生中,成绩最高的学生信息及其成绩
select st.*,sc.s_score
from student st
join score sc on st.s_id = sc.s_id
where sc.c_id in (select c.c_id
from course c
join teacher t on c.t_id = t.t_id
where t.t_name = '张三')
and sc.s_score = (select max(sc.s_score)
from teacher t
join course c on t.t_id = c.t_id
join score sc on c.c_id = sc.c_id
where t.t_name = '张三')
-- 写法简单,效率低
select st.*,sc.s_score
from teacher t
join course c on t.t_id = c.t_id
join score sc on c.c_id = sc.c_id
join student st on sc.s_id = st.s_id
where t.t_name = '张三'
order by sc.s_score desc
limit 0,1
- 查询所有课程中成绩相同的学生的学生编号、课程编号、学生成绩
select *
from score
where s_score in (select s_score
from score
group by s_score
having count(*) > 1)
- 查询每门功成绩最好的前两名
select s1.c_id,s1.s_id,count(distinct s2.s_score) +1 as ranks
from score s1
left join score s2 on s1.c_id = s2.c_id and s1.s_score < s2.s_score
group by s1.c_id,s1.s_id
having ranks <= 2
order by s1.c_id,ranks
select s1.c_id,s1.s_id,s1.s_score
from score s1
where (select count(1)
from score s2
where s1.c_id = s2.c_id and s1.s_score < s2.s_score) < 2
order by s1.c_id
- 统计每门课程的学生选修人数(超过5人的课程才统计)。要求输出课程号和选修人数,查询结果按人数降序排列,若人数相同,按课程号升序排列
select c_id,count(s_id) as cnt
from score
group by c_id
having cnt >= 5
order by cnt desc,c_id asc
- 检索至少选修两门课程的学生学号
select s_id
from score
group by s_id
having count(c_id) >= 2
- 查询选修了全部课程的学生信息
select st.*
from student st
join score sc on st.s_id = sc.s_id
group by st.s_id
having count(sc.c_id) = (select count(1) from course)
select *
from student
where s_id in (select s_id
from score
GROUP BY s_id
HAVING count(*)=(select count(*) from course))
- 查询各学生的年龄 – 按照出生日期来算,当前月日 < 出生年月的月日则,年龄减一
select s_birth,
date_format(now(),'%Y')
-date_format(s_birth,'%Y')
-(case when date_format(now(),'%m%d') >= date_format(s_birth,'%m%d') then 0 else 1 end)
as age
from student
-- timestampdiff 函数
select s_birth,timestampdiff(year,s_birth,now()) as age
from student
- 查询本周过生日的学生
- 查询下周过生日的学生
- 查询本月过生日的学生
select * from student where MONTH(DATE_FORMAT(NOW(),'%Y%m%d')) =MONTH(s_birth)
- 查询下月过生日的学生
难题
- 每个学生的总成绩排名、相对于平均总成绩的偏差、相对于同性别学生平均总成绩的偏差
select t1.*,
st.s_sex,
count(t2.sum_score) +1 as ranks,
t1.sum_score - (select avg(sum_score)
from (select s_id,sum(s_score) as sum_score
from score
group by s_id) a)
as '偏差1',
t1.sum_score - (select c.avg_sum
from (select b.s_sex,avg(`sum(s_score)`) as avg_sum
from (select s_id,sum(s_score)
from score sc
group by s_id) a
join student b on a.s_id = b.s_id
group by b.s_sex) c
where c.s_sex =st.s_sex)
as '偏差2'
from (select s_id,sum(s_score) as sum_score
from score
group by s_id) t1
left join (select s_id,sum(s_score) as sum_score
from score
group by s_id) t2 on t1.sum_score < t2.sum_score
join student st on t1.s_id = st.s_id
group by t1.s_id,st.s_sex
order by ranks
- 每个教师所教授的课程中成绩最好的学生及其成绩
-- 正确答案
select st.s_id,st.s_name,sc.s_score,t.t_id,t.t_name
from teacher t
join course c on t.t_id = c.t_id
join score sc on c.c_id = sc.c_id
join student st on sc.s_id = st.s_id
join (select t1.t_id,max(sc1.s_score)
from teacher t1
join course c1 on t1.t_id = c1.t_id
join score sc1 on c1.c_id = sc1.c_id
group by t1.t_id) a on t.t_id = a.t_id
where sc.s_score = a.`max(sc1.s_score)`
-- 错误语句示例:当张三和李四的课程中最高分都是小明且分数相同时,结果显示错误
select st.s_id,st.s_name,sc.s_score,t.t_id,t.t_name
from teacher t
join course c on t.t_id = c.t_id
join score sc on c.c_id = sc.c_id
join student st on sc.s_id = st.s_id
where exists (select 1
from (select t1.t_id,max(sc1.s_score)
from teacher t1
join course c1 on t1.t_id = c1.t_id
join score sc1 on c1.c_id = sc1.c_id
group by t1.t_id) a
where a.t_id = t.t_id and a.`max(sc1.s_score)` = sc.s_score)
- 找出所有学生的姓名、性别、所选课程的名称和成绩,同时标记出哪些学生的某门课程成绩高于该课程的平均成绩
select st.s_name,
st.s_sex,
c.c_name,
sc.s_score,
(case when sc.s_score > (select avg(s_score)
from score
where c_id = sc.c_id)
then 1 else 0 end) as '是否高于平均成绩'
from student st
left join score sc on st.s_id = sc.s_id
left join course c on sc.c_id = c.c_id
order by sc.c_id,st.s_id
- 计算出每个学生在每门课程中的成绩排名
select st.s_name,b1.s_score as '语文',b1.ranks as '语文排名',
b2.s_score as '数学',b2.ranks as '数学排名',
b3.s_score as '英语',b3.ranks as '英语排名'
from student st
left join (select a1.s_id,a1.s_name,a1.s_score,a1.c_id,count(a2.s_score) +1 as ranks
from (select st.s_id ,st.s_name,sc.s_score,c.c_id
from student st
left join score sc on st.s_id = sc.s_id
left join course c on sc.c_id = c.c_id
where c.c_name = '语文') as a1
left join (select st.s_id ,st.s_name,sc.s_score,c.c_id
from student st
left join score sc on st.s_id = sc.s_id
left join course c on sc.c_id = c.c_id
where c.c_name = '语文') as a2 on a1.s_score < a2.s_score
group by a1.s_id) b1 on st.s_id = b1.s_id
left join (select a1.s_id,a1.s_name,a1.s_score,a1.c_id,count(a2.s_score) +1 as ranks
from (select st.s_id ,st.s_name,sc.s_score,c.c_id
from student st
left join score sc on st.s_id = sc.s_id
left join course c on sc.c_id = c.c_id
where c.c_name = '数学') as a1
left join (select st.s_id ,st.s_name,sc.s_score,c.c_id
from student st
left join score sc on st.s_id = sc.s_id
left join course c on sc.c_id = c.c_id
where c.c_name = '数学') as a2 on a1.s_score < a2.s_score
group by a1.s_id) b2 on st.s_id = b2.s_id
left join (select a1.s_id,a1.s_name,a1.s_score,a1.c_id,count(a2.s_score) +1 as ranks
from (select st.s_id ,st.s_name,sc.s_score,c.c_id
from student st
left join score sc on st.s_id = sc.s_id
left join course c on sc.c_id = c.c_id
where c.c_name = '英语') as a1
left join (select st.s_id ,st.s_name,sc.s_score,c.c_id
from student st
left join score sc on st.s_id = sc.s_id
left join course c on sc.c_id = c.c_id
where c.c_name = '英语') as a2 on a1.s_score < a2.s_score
group by a1.s_id) b3 on st.s_id = b3.s_id
select st.s_id,st.s_name,a.c_id,a.s_score,a.ranks
from student st
left join (select s1.s_id,s1.c_id,s1.s_score,count(s2.s_score) +1 as ranks
from score s1
left join score s2 on s1.c_id = s2.c_id and s1.s_score < s2.s_score
group by s1.s_id,s1.c_id) a on st.s_id = a.s_id
join course c on a.c_id = c.c_id
order by a.c_id,a.ranks