sql语句练习(自用)

测试数据

  • 学生表
    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语法注意事项

  1. 单引号和反引号区别

反引号作用于列字段,使用单引号表示是一个字符串

在这里插入图片描述
列属性也可以不用符号
在这里插入图片描述

  1. 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
  1. sql优化:(not) exists 代替 (not) in
    在这里插入图片描述ps:
    在这里插入图片描述

  2. group_concat( )聚合函数
    在这里插入图片描述

  3. select 分组后的属性里再使用select
    在这里插入图片描述

在这里插入图片描述

  1. 查询xx率
    在这里插入图片描述

  2. 排名,mysql没有rank函数 – 两张相同表连接,再比较大小,分组后计算比a大或者小的数量
    在这里插入图片描述

  3. 日期相关函数
    在这里插入图片描述

  4. 左外连接,有外连接
    左外连接:左表全部都有,左右两表能不能匹配是看 on 条件的左右两边 ,而不是看表在sql语句中的前后顺序

常规题目

  1. 查询"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
  1. 查询"01"课程比"02"课程成绩低的学生的信息及课程分数
  2. 查询平均成绩大于等于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) 四舍五入

  1. 查询平均成绩小于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
  1. 查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩
-- 用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
  1. 查询"李"姓老师的数量
select count(1)
from teacher
where t_name like '李%'
  1. 查询学过"张三"老师授课的同学的信息
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 = '张三'
  1. 查询没学过"张三"老师授课的同学的信息
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
)
  1. 查询学过编号为"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';
  1. 查询学过编号为"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 更高效,因为它们在找到第一个匹配的行后就会停止搜索。

  1. 查询没有学全所有课程的同学的信息
-- 直接查
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)) 
  1. 查询至少有一门课与学号为"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'))
  1. 查询和"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')
	)
  1. 查询没学过"张三"老师讲授的任一门课程的学生姓名(不是没学过张三老师课的学生)
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 = '张三'))

  1. 查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩
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
  1. 检索"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
  1. 按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩
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
  1. 查询各科成绩最高分、最低分和平均分:以如下形式显示:课程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
  1. 按各科成绩进行排序,并显示排名
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

在这里插入图片描述

  1. 查询学生的总成绩并进行排名
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
  1. 查询不同老师所教不同课程平均分从高到低显示
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
  1. 查询所有课程的成绩第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

在这里插入图片描述

  1. 统计各科成绩各分数段人数:课程编号,课程名称,[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
  1. 查询学生平均成绩及其名次
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

在这里插入图片描述

  1. 查询各科成绩前三名的记录
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

在这里插入图片描述

  1. 查询每门课程被选修的学生数
select c_id,count(s_id)
from score
group by c_id
  1. 查询出只有两门课程的全部学生的学号和姓名
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
  1. 查询男生、女生人数
select s_sex,count(*)
from student 
group by s_sex
  1. 查询名字中含有"风"字的学生信息
select *
from student
where s_name like '%风%'
  1. 查询相同姓名且相同性别的学生名单,并统计同名人数
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
  1. 查询1990年出生的学生名单
select *
from student
where s_birth like '1990%'
  1. 查询每门课程的平均成绩,结果按平均成绩降序排列,平均成绩相同时,按课程编号升序排列
select c_id,avg(s_score) as avg_score
from score 
group by c_id
order by avg_score desc,c_id asc
  1. 查询平均成绩大于等于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
  1. 查询课程名称为"数学",且分数低于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
  1. 查询所有学生的课程及分数情况
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
  1. 查询任何一门课程成绩在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
  1. 查询不及格的课程
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
  1. 查询课程编号为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
  1. 求每门课程的学生人数
select c_id,count(s_id)
from score
group by c_id
  1. 查询选修"张三"老师所授课程的学生中,成绩最高的学生信息及其成绩
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
  1. 查询所有课程中成绩相同的学生的学生编号、课程编号、学生成绩
select *
from score
where s_score in (select s_score
									from score
									group by s_score
									having count(*) > 1)

在这里插入图片描述

  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
  1. 统计每门课程的学生选修人数(超过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
  1. 检索至少选修两门课程的学生学号
select s_id
from score
group by s_id
having count(c_id) >= 2
  1. 查询选修了全部课程的学生信息
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))
  1. 查询各学生的年龄 – 按照出生日期来算,当前月日 < 出生年月的月日则,年龄减一
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
  1. 查询本周过生日的学生
  2. 查询下周过生日的学生
  3. 查询本月过生日的学生
select * from student where MONTH(DATE_FORMAT(NOW(),'%Y%m%d')) =MONTH(s_birth)
  1. 查询下月过生日的学生

难题

  1. 每个学生的总成绩排名、相对于平均总成绩的偏差、相对于同性别学生平均总成绩的偏差
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

在这里插入图片描述

  1. 每个教师所教授的课程中成绩最好的学生及其成绩
-- 正确答案
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)

在这里插入图片描述

  1. 找出所有学生的姓名、性别、所选课程的名称和成绩,同时标记出哪些学生的某门课程成绩高于该课程的平均成绩
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

在这里插入图片描述

  1. 计算出每个学生在每门课程中的成绩排名
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

在这里插入图片描述

  • 24
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值