MySQL经典练习50题(下)(解析版)

所有笔记、生活分享首发于个人博客
想要获得最佳的阅读体验(无广告且清爽),请访问本篇笔记

书接上回(1-25)

经典50题(26-50)

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

sql 复制代码
SELECT c.c_name,COUNT(DISTINCT sc.s_id) AS s_num
FROM Score sc 
JOIN Course c ON sc.c_id=c.c_id
GROUP BY c.c_name

成绩表按科目对s_id计数

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

sql 复制代码
SELECT s.s_id,s.s_name
FROM Score sc
JOIN Student s ON sc.s_id=s.s_id
GROUP BY s.s_id
HAVING COUNT(DISTINCT sc.c_id)=2

成绩表按学生对c_id计数

查询男女生人数

sql 复制代码
SELECT s_sex,COUNT(DISTINCT s_id) AS '人数'
FROM Student
GROUP BY s_sex

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

sql 复制代码
SELECT * 
FROM Student
WHERE s_name LIKE '%风%'

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

SQL 复制代码
SELECT   s.s_name,  s.s_sex,  COUNT(*) AS same_name_sex_count
FROM   Student AS s
GROUP BY   s.s_name,   s.s_sex
HAVING   COUNT(*) > 1
ORDER BY   s.s_name,   same_name_sex_count DESC;
  1. GROUP BY s.s_name, s.s_sex:根据学生的姓名和性别进行分组,这样具有相同姓名和性别的学生会被分为一组。
  2. HAVING COUNT(*) > 1HAVING 子句用于筛选分组后的结果。这里它用来找出那些出现次数大于1的组,即同名同性的学生。

查询 1990 年出生的学生信息

sql 复制代码
SELECT *
FROM Student
WHERE YEAR(DATE(s_birth))=1990

DATE() 可以将varchar转成日期型

YEAR() 函数返回一个指定日期or时间的年份值,范围为1000到9999,如果日期为零,YEAR()函数返回0

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

SQL 复制代码
SELECT c.c_name,ROUND(AVG(sc.s_score),2) AS '平均分'
FROM Score sc 
JOIN Course c ON sc.c_id=c.c_id
GROUP BY c.c_id
ORDER BY AVG(sc.s_score) DESC,c.c_id ASC

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

SQL 复制代码
SELECT s.s_id,s.s_name,ROUND(AVG(sc.s_score),2) AS '平均成绩'
FROM Score sc 
JOIN Student s ON sc.s_id=s.s_id
GROUP BY s.s_id
HAVING AVG(sc.s_score)>=85
ORDER BY AVG(sc.s_score) DESC

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

sql 复制代码
SELECT s.s_name,sc.s_score
FROM Score sc 
JOIN Student s ON sc.s_id=s.s_id
WHERE c_id=(SELECT c_id FROM Course WHERE c_name='数学')
AND s_score<60
##这题连接三张表也可以

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

sql 复制代码
SELECT 
  s.s_name,
  SUM(CASE WHEN c.c_name = '语文' THEN sc.s_score ELSE 0 END) AS 语文,
  SUM(CASE WHEN c.c_name = '数学' THEN sc.s_score ELSE 0 END) AS 数学,
  SUM(CASE WHEN c.c_name = '英语' THEN sc.s_score ELSE 0 END) AS 英语,
  SUM(sc.s_score) AS 总分
FROM 
  Student s
LEFT JOIN 
  Score sc ON s.s_id = sc.s_id
LEFT JOIN 
  Course c ON sc.c_id = c.c_id
GROUP BY 
  s.s_name, s.s_id; -- 增加 s.s_id 以确保正确分组

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

sql 复制代码
SELECT s.s_name,c.c_name,sc.s_score
FROM Score sc
JOIN Student s ON sc.s_id=s.s_id
JOIN Course c ON sc.s_id=c.c_id
WHERE s_score>70

查询不及格的课程

sql 复制代码
SELECT sc.c_id,c.c_name,sc.s_score
FROM Score sc 
JOIN Course c ON sc.c_id=c.c_id
WHERE sc.s_score<60

查询课程编号为 01 且课程成绩大于等于 80 的学生的学号和姓名

sql 复制代码
SELECT s.s_id,s.s_name
FROM Score sc 
LEFT JOIN Student s ON sc.s_id=s.s_id
WHERE c_id='01'
AND s_score>=80

每门课程的学生人数

sql 复制代码
SELECT c.c_name,count(DISTINCT sc.s_id) AS '人数'
FROM Score sc
JOIN Course c ON sc.c_id=c.c_id
GROUP BY c.c_name

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

sql 复制代码
SELECT   s.*,  MAX(sc.s_score) AS 最高成绩
FROM   Student AS s
JOIN   Score AS sc ON s.s_id = sc.s_id
JOIN   Course AS c ON sc.c_id = c.c_id
JOIN   Teacher AS t ON c.t_id = t.t_id
WHERE   t.t_name = '张三'
GROUP BY   s.s_id,   s.s_name -- 避免同名
ORDER BY   最高成绩 DESC
LIMIT 1;

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

SQL 复制代码
SELECT sc1.s_id,sc1.c_id,sc1.s_score
FROM Score AS sc1
JOIN Score AS sc2 ON sc1.s_score = sc2.s_score  AND sc1.c_id <> sc2.c_id
GROUP BY sc1.s_id, sc1.c_id, sc1.s_score
HAVING 		COUNT(DISTINCT sc2.c_id) > 1;
  1. 将成绩表自身进行连接(自连接),连接条件是两个不同的成绩记录具有相同的分数,但课程编号不同。
  2. HAVING 子句用于筛选分组后的结果,这里它用来找出那些在多个不同课程中具有相同成绩的学生记录。

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

sql 复制代码
SELECT r.*	
FROM(
SELECT c_name,s_name,s_score,
ROW_NUMBER()OVER(PARTITION BY c_name ORDER BY s_score DESC) as rank_num
FROM Score sc 
JOIN Course c ON sc.c_id=c.c_id
JOIN student s ON sc.s_id=s.s_id)  r
WHERE r.rank_num<=2

窗口函数 ROW_NUMBER() 为每个课程 (PARTITION BY c_name) 的成绩分配一个唯一的序号,按分数降序排列 (ORDER BY s_score DESC)。

通过相应的 ID 关联这三个表,以获取完整的课程和学生信息以及他们的分数。

最后通过where筛选出每门课程成绩排名前两名的学生。

统计每门课程的学生选修人数(超过 5 人的课程才统计)。要求输出课程号和选修人数,查询结果按人数降序排列, 若人数相同,按课程号升序排列

SQL 复制代码
SELECT c_id,COUNT(DISTINCT s_id) AS NUMS
FROM Score
GROUP BY c_id
ORDER BY NUMS DESC,c_id ASC

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

SQL 复制代码
SELECT s_id
FROM Score
GROUP BY s_id
HAVING COUNT(DISTINCT c_id)>=2S

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

sql 复制代码
SELECT s.*
FROM student s
JOIN score sc ON s.s_id = sc.s_id
GROUP BY s.s_id
HAVING COUNT(DISTINCT c_id)=(SELECT COUNT(*)FROM course)

查询各学生的年龄:按照出生日期来算,当前月日 < 出生年月的月日则,年龄减 1

sql 复制代码
SELECT s.*,
CASE 
	WHEN MONTH(NOW())<MONTH(DATE(s_birth)) THEN
		YEAR(NOW())-YEAR(DATE(s_birth))-1
	WHEN MONTH(NOW())=MONTH(DATE(s_birth)) AND DAY(NOW())<DAY(DATE(s_birth)) THEN
		YEAR(NOW())-YEAR(DATE(s_birth))-1
	ELSE
		YEAR(NOW())-YEAR(DATE(s_birth))
END AS age
FROM Student s

查询本周过生日的学生

sql 复制代码
SELECT s.*
FROM student s
WHERE WEEK(DATE(s.s_birth))=WEEK(NOW())

查询下周过生日的学生

sql 复制代码
SELECT s.*
FROM student s
WHERE WEEK(DATE(s.s_birth))=WEEK(NOW())+1

查询本月过生的同学

sql 复制代码
SELECT s.*
FROM student s
WHERE MONTH(DATE(s.s_birth))=MONTH(NOW())

查询下月过生日的学生

sql 复制代码
SELECT s.*
FROM student s
WHERE MONTH(DATE(s.s_birth))=MONTH(NOW())+1
相关推荐
敲代码敲到头发茂密3 分钟前
基于 LangChain 实现数据库问答机器人
数据库·人工智能·语言模型·langchain·机器人
一入程序无退路36 分钟前
c语言传参数路径太长,导致无法获取参数
linux·c语言·数据库
陌夏微秋1 小时前
STM32单片机芯片与内部47 STM32 CAN内部架构 介绍
数据库·stm32·单片机·嵌入式硬件·架构·信息与通信
计算机学无涯2 小时前
Spring事务回滚
数据库·sql·spring
web130933203982 小时前
flume对kafka中数据的导入导出、datax对mysql数据库数据的抽取
数据库·kafka·flume
张声录12 小时前
【ETCD】【实操篇(二十)】浅谈etcd集群管理的艺术:从两阶段配置到灾难恢复的设计原则
数据库·etcd
qq_254674412 小时前
数据仓库和数据湖 数据仓库和数据库
数据库·数据仓库
--FGC--3 小时前
【第2篇】 Python与数据库基础
数据库·python·oracle
web135085886354 小时前
9. 大数据集群(PySpark)+Hive+MySQL+PyEcharts+Flask:信用贷款风险分析与预测
大数据·hive·mysql
Y.O.U..4 小时前
Mysq学习-Mysql查询(4)
数据库·学习·mysql