SQL语句加强练习(MySQL8.0为例)

数据表介绍

  • 学生表

Student(SId,Sname,Sage,Ssex)

SId 学生编号,Sname 学生姓名,Sage 出生年月,Ssex 学生性别

  • 课程表

Course(CId,Cname,TId)

CId 课程编号,Cname 课程名称,TId 教师编号

  • 教师表

Teacher(TId,Tname)

TId 教师编号,Tname 教师姓名

  • 成绩表

SC(SId,CId,score)

SId 学生编号,CId 课程编号,score 分数

SQL语句

  • 学生表 Student
create table Student(SId varchar(10),Sname varchar(10),Sage datetime,Ssex varchar(10));
insert into Student values('01' , '赵雷' , '1990-01-01' , '男');
insert into Student values('02' , '钱电' , '1990-12-21' , '男');
insert into Student values('03' , '孙风' , '1990-12-20' , '男');
insert into Student values('04' , '李云' , '1990-12-06' , '男');
insert into Student values('05' , '周梅' , '1991-12-01' , '女');
insert into Student values('06' , '吴兰' , '1992-01-01' , '女');
insert into Student values('07' , '郑竹' , '1989-01-01' , '女');
insert into Student values('09' , '张三' , '2017-12-20' , '女');
insert into Student values('10' , '李四' , '2017-12-25' , '女');
insert into Student values('11' , '李四' , '2012-06-06' , '女');
insert into Student values('12' , '赵六' , '2013-06-13' , '女');
insert into Student values('13' , '孙七' , '2014-06-01' , '女');
  • 课程表 Course
create table Course(CId varchar(10),Cname nvarchar(10),TId varchar(10));
insert into Course values('01' , '语文' , '02');
insert into Course values('02' , '数学' , '01');
insert into Course values('03' , '英语' , '03');
  • 教师表 Teacher
create table Teacher(TId varchar(10),Tname varchar(10));
insert into Teacher values('01' , '张三');
insert into Teacher values('02' , '李四');
insert into Teacher values('03' , '王五');
  • 成绩表 SC
create table SC(SId varchar(10),CId varchar(10),score decimal(18,1));
insert into SC values('01' , '01' , 80);
insert into SC values('01' , '02' , 90);
insert into SC values('01' , '03' , 99);
insert into SC values('02' , '01' , 70);
insert into SC values('02' , '02' , 60);
insert into SC values('02' , '03' , 80);
insert into SC values('03' , '01' , 80);
insert into SC values('03' , '02' , 80);
insert into SC values('03' , '03' , 80);
insert into SC values('04' , '01' , 50);
insert into SC values('04' , '02' , 30);
insert into SC values('04' , '03' , 20);
insert into SC values('05' , '01' , 76);
insert into SC values('05' , '02' , 87);
insert into SC values('06' , '01' , 31);
insert into SC values('06' , '03' , 34);
insert into SC values('07' , '02' , 89);
insert into SC values('07' , '03' , 98);

练习题目

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

SQL语句

SELECT s.*, s1.CId, s1.score, s2.CId, s2.score
FROM Student as s, SC as s1, SC as s2
WHERE s.SId = s1.SId AND s.SId = s2.SId AND
	     s1.CId = '01' AND s2.CId = '02' AND
	     s1.score > s2.score

结果

 查询同时存在" 01 "课程和" 02 "课程的情况

SQL语句

SELECT s1.*, s2.CId, s2.score
FROM SC as s1, SC as s2
WHERE s1.SId = s2.SId AND
	     s1.CId = '01' AND s2.CId = '02'

结果

 查询存在" 01 "课程但可能不存在" 02 "课程的情况(不存在时显示为 null )

SQL语句

SELECT s1.*, s2.CId,s2.score
FROM( SELECT * 
	    FROM SC
	    WHERE SC.CId = '01') AS s1
LEFT JOIN (SELECT *
		   FROM SC
	           WHERE SC.CId = '02') AS s2
ON s1.SId = s2.SId

结果

 查询不存在" 01 "课程但存在" 02 "课程的情况

SQL语句

SELECT s2.SId, s1.CId, s1.score, s2.CId, s2.score
FROM( SELECT * 
	    FROM SC
	    WHERE SC.CId = '01') AS s1
RIGHT JOIN (SELECT *
		   FROM SC
	           WHERE SC.CId = '02') AS s2
ON s1.SId = s2.SId

结果

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

 SQL语句

SELECT s.SId, s.Sname, a.average_score
FROM (SELECT SId, AVG(score) as average_score
	    FROM SC
	    GROUP BY SId) as a
	    LEFT JOIN Student as s
	    ON a.SId = s.SId
WHERE a.average_score >= 60

结果

 查询在 SC 表存在成绩的学生信息

SQL语句

SELECT *
FROM Student
WHERE SId in (SELECT DISTINCT SId
			FROM SC)

 结果

 查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩(没成绩的显示为 null)

SQL语句

SELECT s.SId, s.Sname, a.course_num, a.sorce_sum
FROM Student as s
	   LEFT JOIN (SELECT SId, COUNT(CId) AS course_num, SUM(score) AS sorce_sum
			      FROM SC
			      GROUP BY SId) AS a 
	   ON s.SId = a.SId

结果

 查询「李」姓老师的数量

SQL语句

SELECT COUNT(*) AS li_num
FROM Teacher
WHERE Tname LIKE '李%'

结果

 查询学过「张三」老师授课的同学的信息

SQL语句

SELECT s.*
FROM Student as s
WHERE SId IN (SELECT SId
			 FROM SC
			 WHERE CId IN (SELECT CId
			 			   FROM Course
			  			   WHERE TId IN (SELECT TId
			 			  			     FROM Teacher
			      			   			     WHERE Tname = '张三')))

结果

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

SQL语句

SELECT *
FROM Student 
WHERE SId IN (SELECT SId
			  FROM SC 
			  GROUP BY SId
			  HAVING COUNT(CId)  < (SELECT COUNT(*) 
								 FROM Course) )

结果

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

SQL语句

SELECT *
FROM Student
WHERE SId IN (SELECT DISTINCT SId
			  FROM SC
			  WHERE CId IN (SELECT CId 
						    FROM SC
						    WHERE SId = '01') AND SId != '01')

结果

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

SQL语句

SELECT *
FROM Student
WHERE SId IN (SELECT DISTINCT SId
			  FROM SC
			  WHERE CId IN (SELECT CId 
						    FROM SC
						    WHERE SId = '01') AND SId != '01'
			  GROUP BY SId
			  HAVING COUNT(CId)>=3)

结果

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

SQL语句

SELECT Sname
FROM Student
WHERE SId NOT IN (SELECT SId
				  FROM SC
				  WHERE CId IN(SELECT CId
							   FROM Course
							   WHERE TId IN (SELECT TId 
										     FROM Teacher
			  							     WHERE Tname = '张三')))

结果

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

SQL语句

SELECT s.SId, s.Sname, AVG(score)
FROM Student as s, SC
WHERE s.SId = SC.SId AND score < 60
GROUP BY SC.SId
HAVING COUNT(*) >= 2

 结果

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

SQL语句

SELECT s.*, score
FROM Student as s, SC
WHERE CId = '01' AND score < 60 AND s.SId = SC.SId
ORDER BY score DESC

结果

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

SQL语句

SELECT SId, 
	     SUM(CASE WHEN CId = '01' THEN score ELSE NULL END) AS score_01,
	     SUM(CASE WHEN CId = '02' THEN score ELSE NULL END) AS score_02,
	     SUM(CASE WHEN CId = '03' THEN score ELSE NULL END) AS score_03,
	    AVG(score) AS average_score
FROM SC
GROUP BY SId
ORDER BY average_score DESC

结果

查询各科成绩最高分、最低分和平均分: 以如下形式显示:课程 ID,课程 name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率。及格为>=60,中等为:70-80,优良为:80-90,优秀为:>=90。要求输出课程号和选修人数,查询结果按人数降序排列,若人数相同,按课程号升序排列

SQL语句

SELECT c.CId AS '课程ID',
	     c.Cname AS '课程name',
	     MAX(score) AS '最高分',
	     MIN(score) AS '最低分',
	     AVG(score) AS '平均分',
	     SUM(CASE WHEN score>=60 THEN 1 ELSE 0 END)/COUNT(*) AS '及格率',
	     SUM(CASE WHEN score>=70 AND score<80 THEN 1 ELSE 0 END)/COUNT(*) AS '中等率',
	     SUM(CASE WHEN score>=80 AND score<90 THEN 1 ELSE 0 END)/COUNT(*) AS '优良率',
	     SUM(CASE WHEN score>=90 THEN 1 ELSE 0 END)/COUNT(*) AS '优秀率'
FROM SC, Course AS c
WHERE SC.CId = c.CId 
GROUP BY c.CId
ORDER BY COUNT(*) DESC, c.CId ASC

结果

按各科成绩进行排序,并显示排名, Score 重复时保留名次空缺

SQL语句

SELECT s.*, rank_01, rank_02, rank_03
FROM Student as s
	LEFT JOIN ( SELECT SId, rank() OVER ( PARTITION BY CId ORDER BY score DESC ) AS rank_01 FROM SC WHERE CId = 01 ) a ON s.SId = a.SId
	LEFT JOIN ( SELECT SId, rank() OVER ( PARTITION BY CId ORDER BY score DESC ) AS rank_02 FROM SC WHERE CId = 02 ) b ON s.SId = b.SId
	LEFT JOIN ( SELECT SId, rank() OVER ( PARTITION BY CId ORDER BY score DESC ) AS rank_03 FROM SC WHERE CId = 03 ) c ON s.SId = c.Sid

结果

 按各科成绩进行排序,并显示排名, Score 重复时合并名次

SQL语句

SELECT s.*, rank_01, rank_02, rank_03
FROM Student as s
	LEFT JOIN ( SELECT SId, dense_rank() OVER ( PARTITION BY CId ORDER BY score DESC ) AS rank_01 FROM SC WHERE CId = 01 ) a ON s.SId = a.SId
	LEFT JOIN ( SELECT SId, dense_rank() OVER ( PARTITION BY CId ORDER BY score DESC ) AS rank_02 FROM SC WHERE CId = 02 ) b ON s.SId = b.SId
	LEFT JOIN ( SELECT SId, dense_rank() OVER ( PARTITION BY CId ORDER BY score DESC ) AS rank_03 FROM SC WHERE CId = 03 ) c ON s.SId = c.Sid

结果

 查询学生的总成绩,并进行排名,总分重复时保留名次空缺

SQL语句

SELECT s.*, rank_total
FROM Student as s
	LEFT JOIN (SELECT SId, rank() OVER (ORDER BY AVG(score) DESC) AS rank_total FROM SC GROUP BY SId) a ON s.SId = a.SId
ORDER BY rank_total ASC

结果

 查询学生的总成绩,并进行排名,总分重复时不保留名次空缺

SQL语句

SELECT s.*, rank_total
FROM Student as s
	LEFT JOIN (SELECT SId, dense_rank() OVER (ORDER BY AVG(score) DESC) AS rank_total FROM SC GROUP BY SId) a ON s.SId = a.SId
ORDER BY rank_total ASC

结果

统计各科成绩各分数段人数:课程编号,课程名称,[00-85],[85-70],[70-60],[60-0] 及所占百分比

SQL语句

SELECT c.CId AS '课程编号',
	     Cname AS '课程名称',
	     a.*
FROM Course as c, 
	   (SELECT CId,
	     		 SUM(CASE WHEN score>=85 AND score<=100 THEN 1 ELSE 0 END)/COUNT(*) AS '100_85',
	     		 SUM(CASE WHEN score>=70 AND score<85 THEN 1 ELSE 0 END)/COUNT(*) AS '85_70',
	     		 SUM(CASE WHEN score>=60 AND score<70 THEN 1 ELSE 0 END)/COUNT(*) AS '70_60',
	     		 SUM(CASE WHEN score>=0 AND score<60 THEN 1 ELSE 0 END)/COUNT(*) AS '60_0'
	   FROM SC
	   GROUP BY CId)  as a
WHERE a.CId = c.CId

结果

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

SQL语句

SELECT *
FROM (SELECT *, rank() OVER(PARTITION BY CId ORDER BY score DESC) AS rank_three
	    FROM SC)  as a
WHERE a.rank_three<=3
ORDER BY a.CId, a.rank_three

结果

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

SQL语句

SELECT c.CId, Cname, COUNT(*) AS '选修人数'
FROM SC, Course as c
WHERE SC.CId = c.CId
GROUP BY CId

 结果

 查询出只选修两门课程的学生学号和姓名

SQL语句

SELECT s.SId, Sname
FROM SC, Student as s
WHERE SC.SId = s.SId
GROUP BY s.SId
HAVING COUNT(*) = 2

结果

查询男生、女生人数

SQL语句

SELECT Ssex, COUNT(*)
FROM Student
GROUP BY Ssex

结果

 查询名字中含有「风」字的学生信息

SQL语句

SELECT *
FROM Student
WHERE Sname LIKE '%风%'

结果

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

SQL语句

SELECT s.*, a.num
FROM Student as s
	   LEFT JOIN (SELECT Sname, Ssex, COUNT(*) AS num 
			      FROM Student
			      GROUP BY Sname, Ssex) AS a
			      ON a.Sname = s.Sname
WHERE
a.num>1

结果

查询 990 年出生的学生名单

SQL语句

SELECT Sname, Sage
FROM Student
WHERE Sage LIKE '1990%'

结果

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

SQL语句

SELECT CId, AVG(score) AS average_score
FROM SC
GROUP BY CId
ORDER BY AVG(score) DESC, CId ASC

 结果

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

SQL语句

SELECT s.SId, Sname, AVG(score) AS average_score
FROM SC, Student as s
WHERE SC.SId = s.SId 
GROUP BY SC.SId
HAVING average_score>=85

 结果

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

SQL语句

SELECT s.Sname, score
FROM Student as s, Course as c, SC
WHERE s.SId = SC.SId AND SC.CId = c.CId AND c.Cname = '数学'
HAVING score<60

结果

查询所有学生的课程及分数情况(存在学生没成绩,没选课的情况)

SQL语句

SELECT s.*, score, c.Cname
FROM Student as s
	   LEFT JOIN SC ON SC.SId = s.SId
	   LEFT JOIN Course as c ON SC.CId = c.CId

结果

 查询任何一门课程成绩在 70 分以上的姓名、课程名称和分数

SQL语句

SELECT Sname, Cname, score
FROM Student as s, SC, Course as c
WHERE s.SId = SC.SId AND SC.CId = c.CId
HAVING score>70

结果

 查询不及格的课程

SQL语句

SELECT Sname, Cname
FROM Student as s, SC, Course as c
WHERE s.SId = SC.SId AND SC.CId = c.CId AND score<60

结果

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

SQL语句

SELECT s.SId, Sname
FROM Student as s, SC
WHERE SC.SId = s.SId AND SC.CId = '01' AND score>=80

 结果

求每门课程的学生人数

SQL语句

SELECT CId, COUNT(*) AS '学生人数'
FROM SC
GROUP BY CId

 结果

成绩不重复,查询选修「张三」老师所授课程的学生中,成绩最高的学生信息及其成绩

SQL语句

SELECT s.*, a.Cname, a.max_score
FROM Student as s, 
	   (SELECT SId, c.Cname, MAX(score) AS max_score
	     FROM SC, Course as c, Teacher as t
	     WHERE t.Tname = '张三' AND  t.TId = c.TId AND
	    		  c.CId = SC.CId) as a
WHERE a.SId = s.SId

 结果

成绩有重复的情况下,查询选修「张三」老师所授课程的学生中,成绩最高的学生信息及其成绩

SQL语句

SELECT s.*, b.score, b.ranking
FROM Student as s,
	  (SELECT SC.SId, SC.score, dense_rank() OVER(ORDER BY score DESC) AS ranking
	   FROM SC
	   WHERE CId = (SELECT CId
			 	    FROM Course
			 	    WHERE TId = (SELECT TId
						  	     FROM Teacher
						  	     WHERE Tname = '张三'))) AS b
WHERE b.ranking = 1 AND b.SId = s.SId

结果

 查询不同课程成绩相同的学生的学生编号、课程编号、学生成绩(有点小问题)

SQL语句

SELECT s1.*, s2.*
FROM SC as s1 JOIN SC as s2
WHERE s1.CId != s2.CId AND s1.score = s2.score AND s1.SId != s2.SId
ORDER BY s1.SId, s1.CId, s1.score

结果

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

SQL语句

SELECT *
FROM (SELECT *, rank() OVER(PARTITION BY CId ORDER BY score DESC) AS rank_two
	    FROM SC)  as a
WHERE a.rank_two<=2
ORDER BY a.CId, a.rank_two

结果

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

SQL语句

SELECT CId, COUNT(*) AS course_num
FROM SC
GROUP BY CId 
HAVING course_num>5

结果

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

SQL语句

SELECT SId, COUNT(*) AS course_num
FROM SC
GROUP BY SId
HAVING course_num>=2

 结果

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

SQL语句

SELECT *
FROM Student
WHERE SId IN(SELECT SId
			 FROM SC
			 GROUP BY SId
			 HAVING COUNT(*) = (SELECT COUNT(*) FROM Course))

结果

查询各学生的年龄,只按年份来算

SQL语句

SELECT Sname, YEAR(NOW())-YEAR(Sage) AS age
FROM Student

结果

按照出生日期来算,当前月日 < 出生年月的月日则,年龄减一

SQL语句

SELECT Sname, TIMESTAMPDIFF(YEAR,Sage,NOW()) AS age
FROM Student

结果

 查询本周过生日的学生

SQL语句

SELECT *
FROM Student
WHERE WEEK(NOW()) = WEEK(Sage)

结果

查询下周过生日的学生

SQL语句

SELECT *
FROM Student
WHERE WEEK(NOW())+1 = WEEK(Sage)

结果

 查询本月过生日的学生

SQL语句

SELECT *
FROM Student
WHERE MONTH(NOW()) =MONTH(Sage)

结果

 查询下月过生日的学生

SQL语句

SELECT *
FROM Student
WHERE MONTH(NOW())+1 =MONTH(Sage)

结果

SQL语句仅供参考,有更好的方法欢迎留言和私信!!

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
MySQL 8.0引入了一种新的特性,称为SQL等待事件(SQL Wait Events),该特性可以用于分析和诊断MySQL数据库中的性能问题。SQL等待事件允许用户监视和跟踪数据库中发生的等待事件,并找出导致性能瓶颈的原因。 SQL等待事件是指当一个SQL语句执行时,可能会因为某种原因而处于等待状态。这些等待事件可能包括锁等待、磁盘IO等待、网络等待等。通过监视和分析这些等待事件,我们可以了解到MySQL数据库中的性能瓶颈所在。 通过使用SQL等待事件,我们可以获得以下几个方面的信息: 1. 等待事件类型:我们可以获知SQL语句实际上是因为何种原因而处于等待状态,比如等待锁、等待磁盘IO等。 2. 等待事件持续时间:可以获知SQL语句在等待事件中停留的时间长度,这有助于我们判断等待事件是否严重影响了SQL语句的性能。 3. 等待事件计数:我们可以获知每个等待事件发生的频率,从而可以找出导致频繁等待的原因。 4. 相关SQL语句:可以获知导致等待事件的具体SQL语句是哪条,从而可以进一步分析和优化这些SQL语句。 通过对SQL等待事件的详细分析,我们可以发现数据库中的性能瓶颈,并针对性地进行优化,从而提高数据库的整体性能。这对于开发人员和DBA来说都是非常有价值的工具和特性,能够帮助他们更好地分析和调优MySQL数据库
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cancri e

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值