经典SQL练习题50道
1.数据表介绍
1.1学生表
Student(SId, Sname, Sage, Ssex)
# SId 学生编号,Sname 学生姓名,Sage 出生年月,Ssex学生性别
1.2课程表
Course(CId, Cname, TId)
# CId 课程编号,Cname 课程名称,TId 教师编号
1.3教师表
Teachaer(TId, Tname)
# TId 教师编号,Tname 教师姓名
1.4成绩表
SC(SId, CId, score)
# SId 学生编号,CId 课程编号,score 分数
2.各表的创建与数据的插入
2.1学生表的创建与数据的插入
# 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", "李四", "1017-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", "女");
2.2 课程表的创建与数据的插入
# Course表的创建
create table Course(
CId varchar(10),
Cname varchar(10),
TId varchar(10)
);
# 插入数据
insert into Course values("01", "语文", "02");
insert into Course values("02", "数学", "01");
insert into Course values("03", "英语", "03");
2.3教师表的创建与数据的插入
# Course表的创建
create table Course(
CId varchar(10),
Cname varchar(10),
TId varchar(10)
);
# 插入数据
insert into Course values("01", "语文", "02");
insert into Course values("02", "数学", "01");
insert into Course values("03", "英语", "03");
2.4成绩表的创建与数据的插入
# 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);
3.练习题目
3.1查询" 01 "课程比" 02 "课程成绩高的学生的信息及课程分数
SELECT
s.*,
sc1.score AS Course01_Score,
sc2.score AS Course02_Score
FROM
Student s
JOIN
(SELECT SId, score FROM SC WHERE CId = '01') sc1 ON s.SId = sc1.SId
JOIN
(SELECT SId, score FROM SC WHERE CId = '02') sc2 ON s.SId = sc2.SId
WHERE
sc1.score > sc2.score;
构建查询:
- 子查询:
- 从
SC
表中分别提取出“01”课程和“02”课程的成绩信息,按学生ID分组。 - 可以使用两个子查询,一个选择
CId = '01'
的记录,另一个选择CId = '02'
的记录。
- 从
- 连接操作:
- 将
Student
表与两个子查询通过SId
进行连接,确保比较的是同一个学生的成绩。 - 如果
Student
表不存在,可以仅在SC
表的基础上通过自连接(self-join)实现,但这样将无法获取学生姓名。
- 将
- 条件筛选:
- 使用
WHERE
子句筛选出“01”课程成绩高于“02”课程成绩的学生。
- 使用
查询结果:
3.1.1查询同时存在" 01 "课程和" 02 "课程的情况
SELECT
s.*,
sc1.score AS Course01_Score,
sc2.score AS Course02_Score
FROM
Student s
JOIN
(SELECT SId, score FROM SC WHERE CId = '01') sc1 ON s.SId = sc1.SId
JOIN
(SELECT SId, score FROM SC WHERE CId = '02') sc2 ON s.SId = sc2.SId;
构建查询:
- 子查询:
- 使用两个子查询分别找出选修了“01”课程和“02”课程的学生ID及其成绩。
- 第一个子查询:
SELECT SId, score FROM SC WHERE CId = '01'
- 第二个子查询:
SELECT SId, score FROM SC WHERE CId = '02'
- 连接操作:
- 将
Student
表与两个子查询结果通过SId
进行连接,确保比较的是同一个学生的信息。 - 可以通过两次自连接
SC
表,或使用两次子查询结果作为派生表进行连接。
- 将
- 条件筛选:
- 确保同一个学生在两个子查询结果中都存在,这可以通过
INNER JOIN
或EXISTS
等方式隐式实现。
- 确保同一个学生在两个子查询结果中都存在,这可以通过
- 选择字段:
- 选择学生的信息以及两门课程的成绩。
查询结果:
3.1.2查询存在" 01 "课程但可能不存在" 02 "课程的情况(不存在时显示为 null )
SELECT
s.SId,
s.Sname,
sc01.score AS Course01_Score,
sc02.score AS Course02_Score
FROM
Student s
LEFT JOIN
SC sc01 ON s.SId = sc01.SId AND sc01.CId = '01'
LEFT JOIN
SC sc02 ON s.SId = sc02.SId AND sc02.CId = '02'
WHERE
sc01.SId IS NOT NULL;
构建查询:
- 主查询:
- 从
Student
表出发,确保所有选修了“01”课程的学生都被包含在结果集中。
- 从
- 连接“01”课程成绩:
- 使用
LEFT JOIN
将Student
表与SC
表连接,筛选出CId = '01'
的记录,以获取“01”课程的成绩。
- 使用
- 连接“02”课程成绩:
- 再次使用
LEFT JOIN
将Student
表(或上一步的结果集)与SC
表连接,筛选出CId = '02'
的记录,以获取“02”课程的成绩。 - 由于是
LEFT JOIN
,即使学生未选修“02”课程,其成绩也会显示为NULL
。
- 再次使用
- 选择字段:
- 选择学生的ID、姓名以及两门课程的成绩。
查询结果:
3.1.3查询不存在" 01 "课程但存在" 02 "课程的情况
SELECT
s.SId,
s.Sname,
sc02.score AS Course02_Score
FROM
Student s
JOIN
SC sc02 ON s.SId = sc02.SId AND sc02.CId = '02'
WHERE
NOT EXISTS (
SELECT 1
FROM SC sc01
WHERE sc01.SId = s.SId AND sc01.CId = '01'
);
构建查询:
- 找出选修了“02”课程的学生:
- 使用子查询或
EXISTS
条件从SC
表中筛选出选修了“02”课程的学生ID。
- 使用子查询或
- 排除选修了“01”课程的学生:
- 使用
NOT EXISTS
或LEFT JOIN
结合WHERE
子句排除那些同时选修了“01”课程的学生。
- 使用
- 连接学生信息:
- 将筛选出的学生ID与
Student
表连接,以获取学生的姓名。
- 将筛选出的学生ID与
- 选择字段:
- 选择学生的ID、姓名以及“02”课程的成绩。
查询结果:
3.2查询平均成绩大于等于 60 分的同学的学生编号和学生姓名和平均成绩
SELECT
s.SId,
s.Sname,
AVG(sc.score) AS AverageScore
FROM
Student s
JOIN
SC sc ON s.SId = sc.SId
GROUP BY
s.SId, s.Sname
HAVING
AVG(sc.score) >= 60;
查询结果:
3.3查询在 SC 表存在成绩的学生信息
SELECT DISTINCT
s.SId,
s.Sname
FROM
Student s
JOIN
SC sc ON s.SId = sc.SId;
查询结果:
3.4查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩(没成绩的显示为 null )
SELECT
s.SId,
s.Sname,
COUNT(sc.CId) AS CourseCount,
SUM(sc.score) AS TotalScore
FROM
Student s
LEFT JOIN
SC sc ON s.SId = sc.SId
GROUP BY
s.SId, s.Sname;
查询结果:
3.4.1查有成绩的学生信息
SELECT DISTINCT
s.SId,
s.Sname
FROM
Student s
INNER JOIN
SC sc ON s.SId = sc.SId;
查询结果:
3.5查询「李」姓老师的数量
SELECT COUNT(*) AS LiTeacherCount
FROM Teacher
WHERE Tname LIKE '李%';
查询结果:
3.6查询学过「张三」老师授课的同学的信息
SELECT DISTINCT s.*
FROM Student s
JOIN SC sc ON s.SId = sc.SId
JOIN Course c ON sc.CId = c.CId
JOIN Teacher t ON c.TId = t.TId
WHERE t.Tname = '张三';
查询结果:
3.7查询没有学全所有课程的同学的信息
WITH TotalCourses AS (
SELECT COUNT(*) AS TotalCourseCount
FROM Course
),
StudentCourseCounts AS (
SELECT SId, COUNT(CId) AS SelectedCourseCount
FROM SC
GROUP BY SId
)
SELECT s.*
FROM Student s
JOIN StudentCourseCounts scc ON s.SId = scc.SId
JOIN TotalCourses tc ON 1=1
WHERE scc.SelectedCourseCount < tc.TotalCourseCount;
查询结果:
3.8查询至少有一门课与学号为" 01 "的同学所学相同的同学的信
SELECT DISTINCT s.*
FROM Student s
JOIN SC sc ON s.SId = sc.SId
WHERE sc.CId IN (
SELECT CId
FROM SC
WHERE SId = '01'
)
AND s.SId <> '01';
查询结果:
3.9查询和" 01 "号的同学学习的课程 完全相同的其他同学的信息
SELECT s.*
FROM Student s
WHERE s.SId <> '01'
AND NOT EXISTS (
SELECT CId
FROM SC
WHERE SId = '01'
AND CId NOT IN (
SELECT CId
FROM SC
WHERE SId = s.SId
)
)
AND NOT EXISTS (
SELECT CId
FROM SC
WHERE SId = s.SId
AND CId NOT IN (
SELECT CId
FROM SC
WHERE SId = '01'
)
);
查询结果:
3.10查询没学过"张三"老师讲授的任一门课程的学生姓名
SELECT s.Sname
FROM Student s
WHERE s.SId NOT IN (
SELECT DISTINCT sc.SId
FROM SC sc
JOIN Course c ON sc.CId = c.CId
JOIN Teacher t ON c.TId = t.TId
WHERE t.Tname = '张三'
);
查询结果:
3.11查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩
SELECT
s.SId,
s.Sname,
AVG(sc.score) AS 平均成绩
FROM
Student s
JOIN
SC sc ON s.SId = sc.SId
WHERE
s.SId IN (
SELECT
SId
FROM
SC
WHERE
score < 60
GROUP BY
SId
HAVING
COUNT(*) >= 2
)
GROUP BY
s.SId, s.Sname
ORDER BY
s.SId;
查询结果:
3.12检索" 01 "课程分数小于 60,按分数降序排列的学生信息
SELECT s.SId, s.Sname, sc.score
FROM Student s
JOIN SC sc ON s.SId = sc.SId
WHERE sc.CId = '01' AND sc.score < 60
ORDER BY sc.score DESC;
查询结果:
3.13按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩
SELECT
s.SId,
s.Sname,
-- 动态拼接每个学生的课程成绩
GROUP_CONCAT(CONCAT(c.Cname, ':', sc.score) ORDER BY c.Cname) AS 所有课程成绩,
AVG(sc.score) AS 平均成绩
FROM
Student s
JOIN
SC sc ON s.SId = sc.SId
JOIN
Course c ON sc.CId = c.CId
GROUP BY
s.SId, s.Sname
ORDER BY
平均成绩 DESC;
查询结果:
3.14查询各科成绩最高分、最低分和平均分:
以如下形式显示:课程 ID,课程 name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率
及格为>=60,中等为:70-80,优良为:80-90,优秀为:>=90
要求输出课程号和选修人数,查询结果按人数降序排列,若人数相同,按课程号升序排列
SELECT
c.CId,
c.Cname,
COUNT(sc.SId) AS 选修人数,
MAX(sc.score) AS 最高分,
MIN(sc.score) AS 最低分,
AVG(sc.score) AS 平均分,
SUM(CASE WHEN sc.score >= 60 THEN 1 ELSE 0 END) / COUNT(sc.SId) AS 及格率,
SUM(CASE WHEN sc.score BETWEEN 70 AND 80 THEN 1 ELSE 0 END) / COUNT(sc.SId) AS 中等率,
SUM(CASE WHEN sc.score BETWEEN 80 AND 90 THEN 1 ELSE 0 END) / COUNT(sc.SId) AS 优良率,
SUM(CASE WHEN sc.score >= 90 THEN 1 ELSE 0 END) / COUNT(sc.SId) AS 优秀率
FROM
Course c
LEFT JOIN
SC sc ON c.CId = sc.CId
GROUP BY
c.CId, c.Cname
ORDER BY
选修人数 DESC, c.CId ASC;
查询结果:
3.15按各科成绩进行排序,并显示排名, Score 重复时保留名次空缺
SELECT
CId,
SId,
score,
RANK() OVER (PARTITION BY CId ORDER BY score DESC) AS ranking
FROM
SC
ORDER BY
CId, ranking;
查询结果:
3.15.1按各科成绩进行排序,并显示排名, Score 重复时合并名次
SELECT
CId,
SId,
score,
DENSE_RANK() OVER (PARTITION BY CId ORDER BY score DESC) AS ranking
FROM
SC
ORDER BY
CId, ranking;
查询结果:
3.16查询学生的总成绩,并进行排名,总分重复时保留名次空缺
SELECT
SId,
SUM(score) AS total_score
FROM
SC
GROUP BY
SId
ORDER BY
total_score DESC;
查询结果:
3.16.1 查询学生的总成绩,并进行排名,总分重复时不保留名次空缺
SELECT
SId,
total_score,
DENSE_RANK() OVER (ORDER BY total_score DESC) AS ranking
FROM (
SELECT
SId,
SUM(score) AS total_score
FROM
SC
GROUP BY
SId
) AS subquery;
查询结果:
3.17统计各科成绩各分数段人数:课程编号,课程名称,[100-85],[85-70],[70-60],[60-0] 及所占百分比
SELECT
c.CId AS 课程编号,
c.Cname AS 课程名称,
-- 统计 [100 - 85] 分数段人数
SUM(CASE WHEN sc.score BETWEEN 85 AND 100 THEN 1 ELSE 0 END) AS `[100-85]`,
-- 计算 [100 - 85] 分数段人数所占百分比
CONCAT(ROUND(SUM(CASE WHEN sc.score BETWEEN 85 AND 100 THEN 1 ELSE 0 END) / COUNT(sc.SId) * 100, 2), '%') AS `[100-85]百分比`,
-- 统计 [85 - 70] 分数段人数
SUM(CASE WHEN sc.score BETWEEN 70 AND 84 THEN 1 ELSE 0 END) AS `[85-70]`,
-- 计算 [85 - 70] 分数段人数所占百分比
CONCAT(ROUND(SUM(CASE WHEN sc.score BETWEEN 70 AND 84 THEN 1 ELSE 0 END) / COUNT(sc.SId) * 100, 2), '%') AS `[85-70]百分比`,
-- 统计 [70 - 60] 分数段人数
SUM(CASE WHEN sc.score BETWEEN 60 AND 69 THEN 1 ELSE 0 END) AS `[70-60]`,
-- 计算 [70 - 60] 分数段人数所占百分比
CONCAT(ROUND(SUM(CASE WHEN sc.score BETWEEN 60 AND 69 THEN 1 ELSE 0 END) / COUNT(sc.SId) * 100, 2), '%') AS `[70-60]百分比`,
-- 统计 [60 - 0] 分数段人数
SUM(CASE WHEN sc.score BETWEEN 0 AND 59 THEN 1 ELSE 0 END) AS `[60-0]`,
-- 计算 [60 - 0] 分数段人数所占百分比
CONCAT(ROUND(SUM(CASE WHEN sc.score BETWEEN 0 AND 59 THEN 1 ELSE 0 END) / COUNT(sc.SId) * 100, 2), '%') AS `[60-0]百分比`
FROM
Course c
JOIN
SC sc ON c.CId = sc.CId
GROUP BY
c.CId, c.Cname
ORDER BY
c.CId;
查询结果:
3.18查询各科成绩前三名的记录
SELECT
CId,
SId,
score
FROM (
SELECT
CId,
SId,
score,
RANK() OVER (PARTITION BY CId ORDER BY score DESC) AS ranking
FROM
SC
) subquery
WHERE
ranking <= 3
ORDER BY
CId, ranking;
查询结果:
3.19查询每门课程被选修的学生数
SELECT
c.CId,
c.Cname,
COUNT(DISTINCT sc.SId) AS 选修学生数
FROM
Course c
LEFT JOIN
SC sc ON c.CId = sc.CId
GROUP BY
c.CId, c.Cname
ORDER BY
c.CId;
查询结果:
3.20查询出只选修两门课程的学生学号和姓名
SELECT
s.SId,
s.Sname
FROM
Student s
JOIN
(
SELECT
SId
FROM
SC
GROUP BY
SId
HAVING
COUNT(CId) = 2
) AS subquery ON s.SId = subquery.SId;
查询结果:
3.21查询男生、女生人数
SELECT
Ssex,
COUNT(SId) AS 人数
FROM
Student
GROUP BY
Ssex;
查询结果:
3.22查询名字中含有「风」字的学生信息
SELECT *
FROM Student
WHERE Sname LIKE '%风%';
查询结果:
3.23查询同名同性学生名单,并统计同名人数
SELECT
Sname,
Ssex,
COUNT(SId) AS 同名人数
FROM
Student
GROUP BY
Sname, Ssex
HAVING
COUNT(SId) > 1;
查询结果:
3.24查询 1990 年出生的学生名单
SELECT *
FROM Student
WHERE YEAR(Sage) = 1990;
查询结果;
3.25查询每门课程的平均成绩,结果按平均成绩降序排列,平均成绩相同时,按课程编号升序排列
SELECT
c.CId,
c.Cname,
AVG(sc.score) AS 平均成绩
FROM
Course c
JOIN
SC sc ON c.CId = sc.CId
GROUP BY
c.CId, c.Cname
ORDER BY
平均成绩 DESC, c.CId ASC;
查询结果:
3.26查询平均成绩大于等于 85 的所有学生的学号、姓名和平均成绩
SELECT
s.SId,
s.Sname,
AVG(sc.score) AS 平均成绩
FROM
Student s
JOIN
SC sc ON s.SId = sc.SId
GROUP BY
s.SId, s.Sname
HAVING
AVG(sc.score) >= 85
ORDER BY
s.SId;
查询结果:
3.27查询课程名称为「数学」,且分数低于 60 的学生姓名和分数
SELECT
s.Sname,
sc.score
FROM
Student s
JOIN
SC sc ON s.SId = sc.SId
JOIN
Course c ON sc.CId = c.CId
WHERE
c.Cname = '数学'
AND sc.score < 60;
查询结果:
3.28查询所有学生的课程及分数情况(存在学生没成绩,没选课的情况)
SELECT
s.SId,
s.Sname,
c.CId,
c.Cname,
sc.score
FROM
Student s
LEFT JOIN
SC sc ON s.SId = sc.SId
LEFT JOIN
Course c ON sc.CId = c.CId
ORDER BY
s.SId, c.CId;
查询结果:
3.29查询任何一门课程成绩在 70 分以上的姓名、课程名称和分数
SELECT
s.Sname,
c.Cname,
sc.score
FROM
Student s
JOIN
SC sc ON s.SId = sc.SId
JOIN
Course c ON sc.CId = c.CId
WHERE
sc.score > 70;
查询结果:
3.30查询不及格的课程
SELECT c.Cname, sc.score
FROM SC sc
JOIN Course c ON sc.CId = c.CId
WHERE sc.score < 60;
查询结果:
3.31查询课程编号为 01 且课程成绩在 80 分以上的学生的学号和姓名
SELECT
s.SId,
s.Sname
FROM
Student s
JOIN
SC sc ON s.SId = sc.SId
WHERE
sc.CId = '01'
AND sc.score > 80;
查询结果:
3.32求每门课程的学生人数
SELECT
CId,
COUNT(DISTINCT SId) AS 学生人数
FROM
SC
GROUP BY
CId;
查询结果:
3.33成绩不重复,查询选修「张三」老师所授课程的学生中,成绩最高的学生信息及其成绩
SELECT
s.SId,
s.Sname,
s.Ssex,
s.Sage,
sc.score
FROM
Student s
JOIN
SC sc ON s.SId = sc.SId
JOIN
Course c ON sc.CId = c.CId
JOIN
Teacher t ON c.TId = t.TId
WHERE
t.Tname = '张三'
ORDER BY
sc.score DESC
LIMIT 1;
查询结果:
3.34成绩有重复的情况下,查询选修「张三」老师所授课程的学生中,成绩最高的学生信息及其成绩
SELECT
s.SId,
s.Sname,
s.Ssex,
s.Sage,
sc.score
FROM
Student s
JOIN
SC sc ON s.SId = sc.SId
JOIN
Course c ON sc.CId = c.CId
JOIN
Teacher t ON c.TId = t.TId
WHERE
t.Tname = '张三'
AND sc.score = (
SELECT
MAX(score)
FROM
SC sc_inner
JOIN
Course c_inner ON sc_inner.CId = c_inner.CId
JOIN
Teacher t_inner ON c_inner.TId = t_inner.TId
WHERE
t_inner.Tname = '张三'
);
3.35查询不同课程成绩相同的学生的学生编号、课程编号、学生成绩
SELECT
sc1.SId,
sc1.CId,
sc1.score
FROM
SC sc1
JOIN
SC sc2 ON sc1.SId = sc2.SId AND sc1.CId != sc2.CId AND sc1.score = sc2.score
ORDER BY
sc1.SId, sc1.CId;
查询结果:
3.36查询每门功成绩最好的前两名
SELECT
SId,
CId,
score
FROM (
SELECT
SId,
CId,
score,
RANK() OVER (PARTITION BY CId ORDER BY score DESC) as ranking
FROM
SC
) ranked
WHERE
ranking <= 2
ORDER BY
CId, ranking;
查询结果:
3.37统计每门课程的学生选修人数(超过 5 人的课程才统计)
SELECT
CId,
COUNT(SId) AS 选修人数
FROM
SC
GROUP BY
CId
HAVING
COUNT(SId) > 5
ORDER BY
选修人数 DESC;
查询结果:
3.38检索至少选修两门课程的学生学号
SELECT
SId
FROM
SC
GROUP BY
SId
HAVING
COUNT(CId) >= 2;
查询结果:
3.39查询选修了全部课程的学生信息
SELECT
s.*
FROM
Student s
WHERE
NOT EXISTS (
SELECT
1
FROM
Course c
WHERE
NOT EXISTS (
SELECT
1
FROM
SC sc
WHERE
sc.SId = s.SId
AND sc.CId = c.CId
)
);
查询结果:
3.40查询各学生的年龄,只按年份来算
SELECT
SId,
Sname,
YEAR(CURRENT_DATE) - YEAR(Sage) AS age
FROM
Student;
查询结果:
3.41按照出生日期来算,当前月日 < 出生年月的月日则,年龄减一
SELECT
SId,
Sname,
-- 使用 CASE 语句判断当前月日与出生月日的关系
CASE
WHEN MONTH(CURRENT_DATE) < MONTH(Sage) OR (MONTH(CURRENT_DATE) = MONTH(Sage) AND DAY(CURRENT_DATE) < DAY(Sage))
THEN YEAR(CURRENT_DATE) - YEAR(Sage) - 1
ELSE YEAR(CURRENT_DATE) - YEAR(Sage)
END AS age
FROM
Student;
查询结果:
3.42查询本周过生日的学生
SELECT
SId,
Sname,
Sage
FROM
Student
WHERE
WEEKOFYEAR(CURRENT_DATE) = WEEKOFYEAR(Sage)
AND YEAR(CURRENT_DATE) = YEAR(Sage);
查询结果:
3.43查询下周过生日的学生
SELECT
SId,
Sname,
Sage
FROM
Student
WHERE
(WEEKOFYEAR(CURRENT_DATE) + 1 = WEEKOFYEAR(Sage) AND YEAR(CURRENT_DATE) = YEAR(Sage))
OR
(WEEKOFYEAR(CURRENT_DATE) = 52 AND WEEKOFYEAR(Sage) = 1 AND YEAR(CURRENT_DATE) + 1 = YEAR(Sage));
查询结果:
3.44查询本月过生日的学生
SELECT
SId,
Sname,
Sage
FROM
Student
WHERE
MONTH(CURRENT_DATE) = MONTH(Sage)
AND YEAR(CURRENT_DATE) = YEAR(Sage);
查询结果:
3.45查询下月过生日的学生
SELECT
SId,
Sname,
Sage
FROM
Student
WHERE
(
-- 正常情况:下个月的月份 = 生日月份,且年份相同
(MONTH(DATE_ADD(CURRENT_DATE, INTERVAL 1 MONTH)) = MONTH(Sage)
AND YEAR(DATE_ADD(CURRENT_DATE, INTERVAL 1 MONTH)) = YEAR(Sage))
OR
-- 跨年情况:当前是 12 月,下个月是 1 月,生日在 1 月且年份为下一年
(MONTH(CURRENT_DATE) = 12
AND MONTH(Sage) = 1
AND YEAR(DATE_ADD(CURRENT_DATE, INTERVAL 1 MONTH)) = YEAR(Sage))
);
查询结果: