sql常见50道查询练习题

avatar
作者
筋斗云
阅读量:0

sql常见50道查询练习题

1. 表创建

在这里插入图片描述

1.1 表创建

#–1.学生表  #Student(s_id,s_name,s_birth,s_sex) –学生编号,学生姓名, 出生年月,学生性别 CREATE TABLE `Student` (     `s_id` VARCHAR(20),     s_name VARCHAR(20) NOT NULL DEFAULT '',     s_brith VARCHAR(20) NOT NULL DEFAULT '',     s_sex VARCHAR(10) NOT NULL DEFAULT '',     PRIMARY KEY(s_id) );  #–2.课程表  #Course(c_id,c_name,t_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) );  /* –3.教师表  Teacher(t_id,t_name) –教师编号,教师姓名  */ CREATE TABLE Teacher(     t_id VARCHAR(20),     t_name VARCHAR(20) NOT NULL DEFAULT '',     PRIMARY KEY(t_id) );  /* –4.成绩表  Score(s_id,c_id,s_score) –学生编号,课程编号,分数 */ Create table Score(     s_id VARCHAR(20),     c_id VARCHAR(20) not null default '',     s_score INT(3),     primary key(`s_id`,`c_id`) ); 

1.2 数据插入

#--插入学生表测试数据 #('01' , '赵雷' , '1990-01-01' , '男') 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); 

2. 简单查询例题(3题)

2.1 查询"李"姓老师的数量

SELECT 	count(1) as cnt FROM 	teacher WHERE 	t_name like "李%" 

2.2 查询男生、女生人数

SELECT 	s.s_sex, 	count(1) as 人数 FROM 	student s group by 	s.s_sex 

2.3 查询名字中含有"风"字的学生信息

SELECT 	* FROM 	student WHERE 	s_name like "%风%" 

3. 日期相关例题(6题)

3.1 查询各学生的年龄

  • (按照出生日期来算,当前月日 < 出生年月的月日则,年龄减一)
    -- if函数  select 	a.*, 	year(NOW())-year(a.s_brith)-if(DATE_FORMAT(now(),"%m%d") >DATE_FORMAT(a.s_brith,"%m%d"),0,1) as age FROM 	student a  -- case函数   select s_brith, 	(DATE_FORMAT(NOW(),'%Y')-DATE_FORMAT(s_brith,'%Y') - (case when DATE_FORMAT(NOW(),'%m%d')>DATE_FORMAT(s_brith,'%m%d') then 0 else 1 end)) as age from student; 

3.2 查询本周过生日的学生

SELECT 	* FROM 	student WHERE 	WEEKOFYEAR(STR_TO_DATE(concat(year(NOW()),DATE_FORMAT(s_brith,'%m%d')),"%Y%m%d"))=WEEKOFYEAR(NOW()) -- 	WEEK(DATE_FORMAT(NOW(),'%Y%m%d'))=WEEK(s_birth) 

3.3 查询下周过生日的学生

SELECT 	* FROM 	student WHERE 	WEEKOFYEAR(STR_TO_DATE(concat(year(NOW()),DATE_FORMAT(s_brith,'%m%d')),"%Y%m%d"))=WEEKOFYEAR(NOW()+interval "7" day) -- 	WEEK(DATE_FORMAT(NOW(),'%Y%m%d'))+1=WEEK(s_birth) 

3.4 查询本月过生日的学生

SELECT 	* FROM 	student WHERE 	MONTH(now())=month(s_brith) 

3.5 查询下月过生日的学生

SELECT 	* FROM 	student WHERE 	MONTH(now()+interval "1" month)=month(s_brith) 

3.6 查询1990年出生的学生名单

SELECT 	* FROM 	student WHERE 	s_brith like "1990%" -- 	left(s_brith,4)="1990" -- 	year(s_brith)="1990" 

4. 开窗函数查询(7题)

4.1 按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩

  • 方法一:开窗函数
    select 	a.*, 	avg(a.s_score) over(PARTITION by a.s_id) as avg_score FROM 	score a 
  • 方法二:临时表连接
    SELECT 	a.*, 	t.avg_score FROM 	score a, 	(SELECT 		a.s_id, 		round(avg(a.s_score),2) as avg_score 	FROM 		score a 	group by 		a.s_id) t WHERE 	a.s_id=t.s_id order by 	t.avg_score desc 
  • 方法三:长型数据转为宽型数据
    SELECT 	a.s_id, 	ifnull((select s_score from score where s_id=a.s_id and c_id="01"),0) as "语文", 	ifnull((select s_score from score where s_id=a.s_id and c_id="02"),0) as "数学", 	ifnull((select s_score from score where s_id=a.s_id and c_id="03"),0) as "英语", 	ifnull(round(avg(a.s_score),2),0) as avg_score FROM 	score a group by 	a.s_id order by 	ifnull(round(avg(a.s_score),2),0) desc 

4.2 按各科成绩进行排序,并显示排名(实现不完全)

  • 方法一:开窗函数
    SELECT 	a.*, 	rank() over(PARTITION by c_id order by s_score desc) rank排名, 	row_number() over(PARTITION by c_id order by s_score desc) row_number排名, 	dense_rank() over(PARTITION by c_id order by s_score desc) dense_rank排名 FROM 	score a 
  • 方法二:子查询
    SELECT	 	a.*, 	(select count(s_score) from score b where a.c_id=b.c_id and  a.s_score<b.s_score)+1 rk, 	(select count(distinct s_score) from score b where a.c_id=b.c_id and  a.s_score<=b.s_score) den_rk FROM 	score a order by 	c_id,s_score desc 

4.3 查询学生的总成绩并进行排名

  • 方法一:开窗函数
    SELECT 	t.*, 	rank() over(order by sum_score desc) rank排名 FROM 	(SELECT 		s_id, 		sum(s_score) as sum_score 	FROM 		score 	group by 		s_id) t 

4.4 查询所有课程的成绩第2名到第3名的学生信息及该课程成绩

  • 方法一:子查询+开窗函数
    SELECT 	a.*, 	t.c_id, 	t.rk, 	t.s_score FROM 	student a, 	(SELECT 		a.s_id, 		a.c_id, 		a.s_score, 		dense_rank() over(PARTITION by a.c_id order by a.s_score desc) as rk 	FROM 		score a) t WHERE 	t.rk in (2,3) AND 	a.s_id=t.s_id  

4.5 查询学生平均成绩及其名次

  • 方法一: 开窗函数
    SELECT 	t.*, 	rank() over(order by t.avg_score desc) 排名 FROM 	(SELECT 		a.s_id, 		round(avg(a.s_score),2) as avg_score 	FROM 		score a 	group by 		a.s_id) t 

4.6 查询各科成绩前三名的记录

  • 方法一:开窗函数
    SELECT 	t.* from 	(SELECT 		a.c_id, 		a.c_name, 		b.s_score, 		rank() over(PARTITION by a.c_id order by b.s_score desc) rk 	FROM 		course a 	LEFT JOIN 		score b 	ON 		a.c_id=b.c_id) t WHERE 	t.rk<=3;  
  • 方法二:子查询
    SELECT 	* from ( 	SELECT 		a.c_id, 		a.c_name, 		b.s_score, 		(select count(c.s_score) from score c where a.c_id=c.c_id and b.s_score<c.s_score)+1 as rk 	FROM 		course a 	LEFT JOIN 		score b 	ON 		a.c_id=b.c_id) t WHERE 	t.rk<=3 order by 	t.c_name,t.rk asc; 

4.7 查询每门功成绩最好的前两名

  • 方法一:开窗函数
    SELECT 	t.s_id, 	t.c_id, 	t.s_score FROM 	(SELECT 		*, 		rank() over(PARTITION by b.c_id order by b.s_score desc) rk 	FROM 		score b) t WHERE 	t.rk<=2; 
  • 方法二:自连接
    SELECT 	t.s_id, 	t.c_id, 	t.s_score FROM 	(SELECT 		a.*, 		(select count(1) from score b where b.c_id=a.c_id and a.s_score<b.s_score)+1 as rk 	FROM 		score a 	order by 		a.c_id,rk) t WHERE	 	t.rk<=2  
  • 方法三:条件查询+子查询
    SELECT 	a.* FROM 	score a WHERE 	(select count(1) from score b where b.c_id=a.c_id and a.s_score<b.s_score)+1<=2 order by 	a.c_id  

5. 表连接+子查询+聚合函数查询(34题)

5.1 查询"01"课程比"02"课程成绩高的学生的信息及课程分数

  • 方法一:自连接,同列比较,使用自查询
    • 思路:先找出查询条件的学生信息及分数,根据子查询得到最终结果
    SELECT st.*,t1.sc1,t1.sc2 FROM  student st, 	(SELECT 		s1.s_id,s1.s_score as sc1,s2.s_score as sc2 	FROM 		score s1,score s2 	WHERE	 		s1.c_id="01" 	AND	 		s2.c_id="02" 	AND 		s1.s_id=s2.s_id 	AND 		s1.s_score>s2.s_score) t1 WHERE 	st.s_id=t1.s_id; 
  • 方法二:表连接
    SELECT st.*,s1.s_score as sc1,s2.s_score as sc2 FROM 	student st left JOIN 	score s1 ON 	s1.s_id=st.s_id left JOIN 	score s2 ON 	s2.s_id=st.s_id WHERE	 	s1.c_id="01" AND	 	s2.c_id="02" AND 	s1.s_id=s2.s_id AND 	s1.s_score>s2.s_score 
  • 数据长型数据变为宽型数据
    -- IF函数或case函数 SELECT 	a.*, 	t.s01, 	t.s02 from 	student a, 	(SELECT 		a.s_id, 		max(case when a.c_id="01" then a.s_score end) as s01, 		max(case when a.c_id="02" then a.s_score end) as s02 --  max(if(a.c_id="01",a.s_score,null)) as s01, --  max(if(a.c_id="02",a.s_score,null)) as s02 	from 		score a 	group by 		a.s_id) t WHERE 	a.s_id=t.s_id AND 	t.s01>t.s02  

5.2 查询"01"课程比"02"课程成绩低的学生的信息及课程分数

  • 与上一题思路一致,条件大于变小于
  • 方法一:自连接
    SELECT st.*,t1.sc1,t1.sc2 FROM  student st, 	(SELECT 		s1.s_id,s1.s_score as sc1,s2.s_score as sc2 	FROM 		score s1,score s2 	WHERE	 		s1.c_id="01" 	AND	 		s2.c_id="02" 	AND 		s1.s_id=s2.s_id 	AND 		s1.s_score<s2.s_score) t1 WHERE 	st.s_id=t1.s_id;  
  • 方法二:表连接
    SELECT 	st.*,s1.s_score as sc1,s2.s_score as sc2 FROM 	student st left JOIN 	score s1 ON 	s1.s_id=st.s_id left JOIN 	score s2 ON 	s2.s_id=st.s_id WHERE	 	s1.c_id="01" AND	 	s2.c_id="02" AND 	s1.s_id=s2.s_id AND 	s1.s_score<s2.s_score 	 -- 方法二 SELECT 	st.*,s1.s_score as sc1,s2.s_score as sc2 FROM 	student st left JOIN 	score s1 ON 	s1.s_id=st.s_id AND 	s1.c_id="01" left JOIN 	score s2 ON 	s2.s_id=st.s_id AND 	s2.c_id="02" AND 	s1.s_id=s2.s_id WHERE 	s1.s_score<s2.s_score  
  • 方法三:数据长型数据变为宽型数据
    -- IF函数或case函数 SELECT 	a.*, 	t.s01, 	t.s02 from 	student a, 	(SELECT 		a.s_id, 		max(case when a.c_id="01" then a.s_score end) as s01, 		max(case when a.c_id="02" then a.s_score end) as s02 --  max(if(a.c_id="01",a.s_score,null)) as s01, --  max(if(a.c_id="02",a.s_score,null)) as s02 	from 		score a 	group by 		a.s_id) t WHERE 	t.s01<t.s02 AND 	a.s_id=t.s_id 

5.3 查询平均成绩大于等于60分的同学的学生编号和学生姓名和平均成绩

  • 方法一:子查询
    -- 子查询一 SELECT st.s_id,st.s_name,t.avg_s FROM 	student ST, 	(SELECT 		s.s_id,round(avg(s.s_score),2) as avg_s 	FROM	 		score s 	GROUP BY 		s.s_id 	HAVING 		round(avg(s.s_score),2)>=60) t WHERE 	st.s_id=t.s_id  -- 方法二:子查询二  SELECT 	s.s_id, 	(select s_name from student where s_id=s.s_id) as s_name, 	round(avg(s.s_score),2) as avg_s FROM	 	score s GROUP BY 	s.s_id HAVING 	avg_s>=60 
  • 方法二:表连接
    SELECT 	a.s_id,a.s_name,round(avg(b.s_score),2) as avg_score FROM 	student a LEFT JOIN 	score b ON 	a.s_id=b.s_id GROUP BY 	a.s_id HAVING 	round(avg(b.s_score),2)>=60; 

5.4 查询平均成绩小于60分的同学的学生编号和学生姓名和平均成绩(包括有成绩的和无成绩的)

  • 方法一:子查询
    -- 有成绩的  SELECT 	a.s_id,a.s_name,t.avg_acore FROM 	student a, 	(SELECT 		a.s_id,round(avg(a.s_score),2) as avg_acore 	FROM 		score a 	GROUP BY 		a.s_id 	HAVING 		round(avg(a.s_score),2)<60) t WHERE 	a.s_id=t.s_id   UNION -- 没有成绩的:没有成绩的s_id不存在 SELECT 	a.s_id,a.s_name,0 as avg_acore FROM 	student a WHERE 	a.s_id not in (SELECT DISTINCT s_id FROM score); 
  • 方法二:表连接
    SELECT 	a.s_id,a.s_name,ifnull(round(avg(b.s_score),2),0) as avg_score FROM 	student a LEFT JOIN 	score b on  	a.s_id=b.s_id GROUP BY 	a.s_id HAVING 	avg_score<60 

5.5 查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩

SELECT 	a.s_id, 	a.s_name, 	count(b.c_id) as cnt_course, 	ifnull(sum(b.s_score),0) as sum_score FROM 	student a LEFT JOIN 	score b ON 	a.s_id=b.s_id group by 	a.s_id  

5.6 查询学过"张三"老师授课的同学的信息

  • 方法一:表连接+子查询单层嵌套
    SELECT 	a.* FROM 	student a LEFT JOIN 	score b on  	a.s_id=b.s_id LEFT JOIN 	course c ON 	b.c_id=c.c_id where c.t_id in(SELECT t_id FROM teacher WHERE t_name = "张三") 
  • 方法二:表连接+子查询多层嵌套
    SELECT 	a.* FROM 	student a LEFT JOIN 	score b ON 	a.s_id=b.s_id WHERE 	b.c_id in ( SELECT 	c_id FROM 	course where t_id in(SELECT t_id from teacher where t_name="张三") ); 
  • 方法三:多表连接
    select 	a.* from 	student a,score b,course c,teacher d WHERE 	a.s_id=b.s_id AND 	b.c_id=c.c_id AND 	c.t_id=d.t_id AND 	d.t_name="张三" 

5.7 查询没学过"张三"老师授课的同学的信息

  • 注意:一个学生有几门课程包含张三课程,不是张三课程的,根据没学过的查询不出来,因为一个人有多个老师的课程
  • 方法一:多层嵌套子查询
    SELECT 	s.* FROM 	student s WHERE 	s.s_id NOT IN ( 		-- 查找学的学生 		SELECT DISTINCT 			a.s_id 		FROM 			student a 		LEFT JOIN score b ON a.s_id = b.s_id 		WHERE 			b.c_id IN ( 				-- 查找学过的课程 				SELECT c_id 				FROM course 				WHERE t_id IN ( SELECT t_id FROM teacher WHERE t_name = "张三") 			) 	) 
  • 方法二:条件查询+子表连接
    SELECT 	* FROM 	student s WHERE 	s.s_id not in ( 				select 					a.s_id 				from 					score a, 					course b, 					teacher c 				WHERE 					a.c_id=b.c_id 				AND 					b.t_id=c.t_id 				AND 					c.t_name="张三") 

5.8 查询学过编号为"01"并且也学过编号为"02"的课程的同学的信息

  • 方法一:子查询+自连接,同列对比可以用自连接
    SELECT 	* FROM 	student s WHERE 	s.s_id in( 					SELECT 						a.s_id 					FROM 						score a,score b 					WHERE 						a.c_id="01"  					AND 						b.c_id="02" 					AND 						a.s_id=b.s_id) 
  • 方法二:连表+自连接,同列对比可以用自连接
    SELECT 	s.* FROM 	student s LEFT JOIN  	score a ON 	s.s_id=a.s_id LEFT JOIN 	score b ON 	a.s_id=b.s_id WHERE 	a.c_id="01"  AND 	b.c_id="02" 
  • 方法三:条件查询+子查询
    SELECT 	* FROM 	student WHERE 	s_id in (SELECT 					s_id 				FROM 					score 				where 					c_id="01" or c_id="02" 				GROUP BY 					s_id 				HAVING 					count(1)=2) 
  • 方法四:自连接,条件连接
    SELECT 	s.* FROM 	student s,score a,score b WHERE 	s.s_id=a.s_id AND 	a.s_id=b.s_id AND 	a.c_id="01"  AND 	b.c_id="02" 
  • 方法五:子查询+数据长型数据变为宽型数据
    SELECT 	a.* FROM 	student a, 	(select 		a.s_id, 		max(if(a.c_id="01",a.s_score,0)) as s01, 		max(if(a.c_id="02",a.s_score,0)) as s02 	from 		score a 	group by 		a.s_id) t WHERE 	a.s_id=t.s_id AND 	t.s01>0 AND 	t.s02>0 

5.9 查询学过编号为"01"但是没有学过编号为"02"的课程的同学的信息

  • 方法一:条件查询+子查询
    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") 
  • 方法二: 子查询+分组聚合
    SELECT 	s.* FROM 	student s, 	( 		SELECT 			a.s_id, 			max(case when a.c_id="01" then a.s_score end) s01, 			max(case when a.c_id="02" then a.s_score end) s02 		FROM 			score a 		group by 			a.s_id) t WHERE 	s.s_id=t.s_id AND 	t.s01 is not NULL AND 	t.s02 is null 
  • 方法三:数据长型数据变为宽型数据
    SELECT 	a.* FROM 	student a, 	(select 		a.s_id, 		max(if(a.c_id="01",a.s_score,null)) as s01, 		max(if(a.c_id="02",a.s_score,null)) as s02 	from 		score a 	group by 		a.s_id) t WHERE 	a.s_id=t.s_id AND 	t.s01 is not null AND 	t.s02 is null 

5.10 查询没有学全所有课程的同学的信息

  • 方法一:条件查询+子查询
    SELECT 	s.* FROM 	student s WHERE 	s.s_id in( 			SELECT 				a.s_id 			FROM 				score a 			group by 				a.s_id 			having 				count(1)<(select count(1) from course)) 
  • 方法二:表连接
    SELECT 	s.*, 	count(a.c_id) cnt FROM 	student s LEFT JOIN 	score a ON 	a.s_id=s.s_id group by 	s.s_id HAVING 	count(a.c_id)<(select count(1) from course) 

5.11 查询至少有一门课与学号为"01"的同学所学相同的同学的信息

  • 方法一:子查询
    SELECT 	s.* FROM 	student s WHERE 	s.s_id in( 			SELECT 				distinct a.s_id 			FROM 				score a 			WHERE 				a.c_id in( 						SELECT 							b.c_id 						FROM 							score b 						WHERE 							b.s_id="01")) AND 	s.s_id!='01' 
  • 方法二:表连接+子查询
    SELECT 	a.* FROM 	student a LEFT JOIN 	score b on  	a.s_id=b.s_id WHERE 	b.c_id in ( 			SELECT 				b.c_id 			FROM 				score b 			WHERE 				b.s_id="01") group by 1,2,3,4 

5.12 查询和"01"号的同学学习的课程完全相同的其他同学的信息

  • 筛选课程与01号一样的数据,计算课程数与01一致的
SELECT 	s.* FROM 	student s WHERE 	s.s_id in( 					SELECT distinct  						a.s_id 					FROM 						score a 					WHERE 						a.c_id in( 								SELECT 									a.c_id 								FROM 									score a 								WHERE 									a.s_id="01") 					AND 						a.s_id!="01" 					group by  						a.s_id 					HAVING 						count(distinct a.c_id)=(select count(1) from score a where a.s_id="01") 					) 

5.13 查询没学过"张三"老师讲授的任一门课程的学生姓名

  • 查询学过张三老师的学生,在学生表中反向查询
SELECT 	s.s_name FROM 	student s WHERE 	s.s_id not in( 				SELECT 					a.s_id 				FROM 					score a 				WHERE 					a.c_id in ( 							SELECT 								a.c_id 							FROM 								course a 							WHERE 								a.t_id in (SELECT t.t_id FROM teacher t WHERE t.t_name="张三"))) 

5.14 查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩

  • 方法一:表连接+分组+having条件
    SELECT 	a.s_id, 	a.s_name, 	round(avg(b.s_score),2) as avg_score FROM 	student a LEFT JOIN 	score b ON 	a.s_id=b.s_id group by 	a.s_id having 	sum(if(b.s_score>=60,0,1))>=2 
  • 方法二:自连接+子查询
    select 	a.s_id,a.s_name,round(avg(b.s_score),2) as avg_score FROM 	student a,score b WHERE 	a.s_id=b.s_id AND 	a.s_id in( 			SELECT 				a.s_id 			FROM 				score a 			WHERE 				a.s_score<60 			group by 				a.s_id 			HAVING 				count(1)>=2) group by 	a.s_id  
  • 方法三:表连接+子查询
    select 	a.s_id,a.s_name,round(avg(b.s_score),2) as avg_score FROM 	student a LEFT JOIN 	score b on 	a.s_id=b.s_id where 	a.s_id in( 			SELECT 				a.s_id 			FROM 				score a 			WHERE 				a.s_score<60 			group by 				a.s_id 			HAVING 				count(1)>=2) group by 	a.s_id 

5.15 检索"01"课程分数小于60,按分数降序排列的学生信息

  • 方法一:表连接
    SELECT 	a.*,b.c_id,b.s_score FROM 	student a LEFT JOIN 	score b ON 	a.s_id=b.s_id WHERE 	b.c_id="01" and b.s_score<60 order by 	b.s_score desc 

5.16 查询各科成绩最高分、最低分和平均分

  • 以如下形式显示:课程ID,课程name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率
  • 及格为>=60,中等为:70-80,优良为:80-90,优秀为:>=90
  • 方法一:if语句
    SELECT 	a.c_id, 	a.c_name, 	max(b.s_score) as max_score, 	min(b.s_score) as min_score, 	round(avg(b.s_score),2) as avg_score, 	round(100*sum(if(b.s_score>=60,1,0))/count(1),2) as "及格率", 	round(100*sum(if(b.s_score>=70 and b.s_score<80,1,0))/count(1),2) as "中等率", 	round(100*sum(if(b.s_score>=80 and b.s_score<90,1,0))/count(1),2) as "优良率", 	round(100*sum(if(b.s_score>=90,1,0))/count(1),2) as "优秀率" FROM 	course a, 	score b WHERE 	a.c_id=b.c_id group by 	a.c_id 
  • 方法二:case when
    SELECT 	a.c_id, 	a.c_name, 	max(b.s_score) as max_score, 	min(b.s_score) as min_score, 	round(avg(b.s_score),2) as avg_score, 	round(100*sum(case when b.s_score>=60 then 1 else 0 end)/sum(case when b.s_score then 1 else 0 end),2) as "及格率", 	round(100*sum(case when b.s_score>=70 and b.s_score<80 then 1 else 0 end)/sum(case when b.s_score then 1 else 0 end),2) as "中等率", 	round(100*sum(case when b.s_score>=80 and b.s_score<90 then 1 else 0 end)/sum(case when b.s_score then 1 else 0 end),2) as "优良率", 	round(100*sum(case when b.s_score>=90 then 1 else 0 end)/sum(case when b.s_score then 1 else 0 end),2) as "优秀率" FROM 	course a, 	score b WHERE 	a.c_id=b.c_id group by 	a.c_id  

5.17 统计各科成绩各分数段人数

  • 课程编号,课程名称,[100-85],[85-70],[70-60],[0-60]个数及所占百分比
  • 方法一:if函数
    SELECT 	b.c_id, 	a.c_name,     round(100*sum(if(b.s_score>85 and b.s_score<=100,1,0))/count(1),2) as "[100-85]百分比", 	sum(if(b.s_score>85 and b.s_score<=100,1,0)) as "[100-85]", 	round(100*sum(if(b.s_score>70 and b.s_score<=85,1,0))/count(1),2) as "[85-70]百分比", 	sum(if(b.s_score>70 and b.s_score<=85,1,0)) as "[85-70]", 	round(100*sum(if(b.s_score>60 and b.s_score<=70,1,0))/count(1),2) as "[70-60]百分比", 	sum(if(b.s_score>60 and b.s_score<=70,1,0)) as "[70-60]", 	round(100*sum(if(b.s_score>0 and b.s_score<=60,1,0))/count(1),2) as "[0-60]百分比", 	sum(if(b.s_score>=0 and b.s_score<=60,1,0)) as "[0-60]" FROM 	course a, 	score b WHERE 	a.c_id=b.c_id group by 	b.c_id 

5.18 查询不同老师所教不同课程平均分从高到低显示

  • 方法一:表连接
    SELECT 	c.t_name, 	a.c_name, 	round(avg(b.s_score),2) as avg_score FROM 	course a left JOIN 	score b ON 	a.c_id=b.c_id LEFT JOIN 	teacher c ON 	a.t_id=c.t_id group by 	c.t_name,a.c_name order by 	avg_score DESC 

5.19 查询每门课程被选修的学生数

SELECT 	a.c_id, 	a.c_name, 	count(1) as cnt FROM 	course a LEFT JOIN 	score b ON	 	a.c_id=b.c_id group by 	a.c_id  

5.20 查询出只有两门课程的全部学生的学号和姓名

  • 方法一:连表
    SELECT 	distinct a.s_id,a.s_name FROM 	student a, 	score b WHERE 	a.s_id=b.s_id group by 	a.s_id HAVING 	count(b.c_id)=2 
  • 方法二:条件查询
    select  	s_id, 	s_name  from  	student  where  	s_id in (select s_id from score GROUP BY s_id HAVING COUNT(c_id)=2); 

5.21 查询同名同性学生名单,并统计同名人数

  • 方法一:分组条件查询
    SELECT 	s_name, 	count(1) as "人数" FROM 	student group by 	s_name,s_sex HAVING 	count(1)>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  

5.22 查询每门课程的平均成绩

  • 结果按平均成绩降序排列,平均成绩相同时,按课程编号升序排列
    SELECT 	a.c_id, 	round(avg(a.s_score),2) as avg_score FROM 	score a group by 	a.c_id order by 	avg_score desc,a.c_id asc	 

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

  • 方法一:子查询
    SELECT 	a.s_id, 	a.s_name, 	t.avg_score FROM 	student a, 	(SELECT 		a.s_id, 		round(avg(a.s_score),2) as avg_score 	FROM 		score a 	group by 		a.s_id 	HAVING 		avg_score>=85) t WHERE	 	a.s_id=t.s_id AND 	t.avg_score is not null 
  • 方法二:表连接
    select 	a.s_id, 	b.s_name, 	ifnull(round(avg(a.s_score),2),0) as avg_score FROM 	score a LEFT JOIN 	student b ON 	a.s_id=b.s_id GROUP BY 	a.s_id HAVING 	avg_score>=85 

5.24 查询课程名称为"数学",且分数低于60的学生姓名和分数

  • 方法一:条件查询+子查询
    SELECT 	b.s_name, 	a.s_score FROM 	score a LEFT JOIN 	student b ON 	a.s_id=b.s_id WHERE 	c_id in (SELECT c_id FROM course where c_name="数学") AND 	a.s_score<60 
  • 方法二:多表连接
    SELECT 	b.s_name, 	a.s_score FROM 	score a LEFT JOIN 	student b ON 	a.s_id=b.s_id LEFT JOIN 	course c ON 	a.c_id=c.c_id WHERE 	c.c_name="数学" AND 	a.s_score<60 

5.25 查询所有学生的课程及分数情况

  • 方法一:表连接
    SELECT 	a.s_name,c.c_name,b.s_score FROM 	student a LEFT JOIN 	score b ON 	a.s_id=b.s_id LEFT JOIN 	course c ON 	c.c_id=b.c_id 
  • 方法二:if函数
    SELECT 	a.s_id, 	a.s_name, 	sum(if(c.c_name="语文",b.s_score,0)) as "语文", 	sum(if(c.c_name="数学",b.s_score,0)) as "数学", 	sum(if(c.c_name="英语",b.s_score,0)) as "英语", 	sum(b.s_score) as "总分" FROM 	student a LEFT JOIN 	score b ON 	a.s_id=b.s_id LEFT JOIN 	course c ON 	c.c_id=b.c_id group by 	a.s_id,a.s_name 
  • 方法三:case函数
    select 	a.s_id, 	a.s_name, 	sum(case when c.c_name="语文" then b.s_score else 0 end) as "语文", 	sum(case when c.c_name="数学" then b.s_score else 0 end) as "数学", 	sum(case when c.c_name="英语" then b.s_score else 0 end) as "英语", 	sum(b.s_score) as "总分" FROM 	student a LEFT JOIN 	score b ON 	a.s_id=b.s_id LEFT JOIN 	course c ON 	c.c_id=b.c_id group by 	a.s_id,a.s_name 

5.26 查询任何一门课程成绩在70分以上的姓名、课程名称和分数(学生的每门课都大于70)

  • 方法一:表连接+子查询
    SELECT 	a.s_name, 	c.c_name, 	b.s_score  FROM 	student a LEFT JOIN 	score b ON 	a.s_id=b.s_id LEFT JOIN 	course c ON 	c.c_id=b.c_id WHERE 	a.s_id in (select s_id from score group by s_id having min(s_score)>70); 

5.27 查询不及格的课程

  • 方法一:表连接
SELECT distinct 	b.s_id, 	b.c_id, 	a.c_name, 	b.s_score from 	course a LEFT JOIN 	score b ON 	a.c_id=b.c_id WHERE 	b.s_score<60 

5.28 查询课程编号为01且课程成绩在80分以上的学生的学号和姓名

  • 方法一:子查询
    SELECT 	t.s_id, 	t.s_name FROM 	student t WHERE 	t.s_id in( 			SELECT 				a.s_id 			FROM 				score a 			WHERE 				a.c_id="01"  			AND 				a.s_score>80) 
  • 方法二:表连接
    select 	a.s_id, 	a.s_name from 	student a LEFT JOIN 	score b ON 	a.s_id=b.s_id WHERE 	b.c_id="01" AND 	b.s_score>80 

5.29 求每门课程的学生人数

SELECT 	a.c_name, 	count(1) as "人数" FROM 	course a LEFT JOIN 	score b ON 	a.c_id=b.c_id group by 	a.c_id 

5.30 查询选修"张三"老师所授课程的学生中,成绩最高的学生信息及其成绩

  • 方法一:表连接+子查询
    SELECT 	a.*, 	b.s_score as max_score, 	b.c_id, 	c.c_name FROM 	student a LEFT JOIN 	score b ON 	a.s_id=b.s_id LEFT JOIN 	course c ON 	c.c_id=b.c_id WHERE -- 查询id 	b.c_id in ( 						SELECT 							c_id 						FROM 							course  						WHERE 							t_id in (select t_id from teacher where t_name="张三") 						) AND -- 查询最大分数 	b.s_score=(select distinct max(s_score) from score where c_id="02") 
  • 方法二:表连接
     SELECT 	a.*, 	b.s_score as max_score, 	b.c_id, 	c.c_name FROM 	student a LEFT JOIN 	score b ON 	a.s_id=b.s_id LEFT JOIN 	course c ON 	c.c_id=b.c_id LEFT JOIN 	teacher d ON 	d.t_id=c.t_id WHERE 	d.t_name="张三" order by 	max_score desc limit 1; 

5.31 查询不同课程成绩相同的学生的学生编号、课程编号、学生成绩

SELECT distinct 	a.* FROM 	score a, 	score b WHERE 	a.c_id!=b.c_id AND 	a.s_score=b.s_score 

5.32 统计每门课程的学生选修人数(超过5人的课程才统计)

  • 要求输出课程号和选修人数,查询结果按人数降序排列,若人数相同,按课程号升序排列
  • 方法一: 分组聚合
    SELECT 	c_id, 	count(1) as "选修人数" FROM 	score group by 	c_id HAVING 	count(1) >5 order by 	"选修人数" desc,c_id asc 
  • 方法二:连表+分组聚合
    SELECT 	a.c_id, 	count(b.s_id) cnt FROM 	course a LEFT JOIN 	score b ON 	a.c_id=b.c_id group by 	a.c_id HAVING 	count(b.s_id)>5 order by 	cnt desc,a.c_id asc 

5.33 检索至少选修两门课程的学生学号

SELECT 	s_id FROM 	score group by 	s_id HAVING 	count(c_id)>=2;      

5.34 查询选修了全部课程的学生信息

  • 方法一:连表查询
    SELECT 	a.* FROM 	student a, 	score b WHERE 	a.s_id=b.s_id group by 	s_id HAVING 	count(1)=(select count(1) from course) 
  • 方法二:子查询
    SELECT 	* FROM 	student a WHERE 	a.s_id in( 		   select  				s_id 			FROM 				score 			group by 				s_id 			HAVING	 				count(1)=(select count(1) from course))  

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!