表的创建
/*
Navicat Premium Data Transfer
Source Server : 本地数据库
Source Server Type : MySQL
Source Server Version : 80031
Source Host : localhost:3306
Source Schema : mysql50
Target Server Type : MySQL
Target Server Version : 80031
File Encoding : 65001
Date: 21/02/2024 17:04:07
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for course
-- ----------------------------
DROP TABLE IF EXISTS `course`;
CREATE TABLE `course` (
`CId` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`Cname` varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL,
`TId` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of course
-- ----------------------------
INSERT INTO `course` VALUES ('01', '语文', '02');
INSERT INTO `course` VALUES ('02', '数学', '01');
INSERT INTO `course` VALUES ('03', '英语', '03');
-- ----------------------------
-- Table structure for sc
-- ----------------------------
DROP TABLE IF EXISTS `sc`;
CREATE TABLE `sc` (
`SId` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`CId` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`score` decimal(18, 1) NULL DEFAULT NULL
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of sc
-- ----------------------------
INSERT INTO `sc` VALUES ('01', '01', 80.0);
INSERT INTO `sc` VALUES ('01', '02', 90.0);
INSERT INTO `sc` VALUES ('01', '03', 99.0);
INSERT INTO `sc` VALUES ('02', '01', 70.0);
INSERT INTO `sc` VALUES ('02', '02', 60.0);
INSERT INTO `sc` VALUES ('02', '03', 80.0);
INSERT INTO `sc` VALUES ('03', '01', 80.0);
INSERT INTO `sc` VALUES ('03', '02', 80.0);
INSERT INTO `sc` VALUES ('03', '03', 80.0);
INSERT INTO `sc` VALUES ('04', '01', 50.0);
INSERT INTO `sc` VALUES ('04', '02', 30.0);
INSERT INTO `sc` VALUES ('04', '03', 20.0);
INSERT INTO `sc` VALUES ('05', '01', 76.0);
INSERT INTO `sc` VALUES ('05', '02', 87.0);
INSERT INTO `sc` VALUES ('06', '01', 31.0);
INSERT INTO `sc` VALUES ('06', '03', 34.0);
INSERT INTO `sc` VALUES ('07', '02', 89.0);
INSERT INTO `sc` VALUES ('07', '03', 98.0);
-- ----------------------------
-- Table structure for student
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
`SId` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`Sname` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`Sage` datetime NULL DEFAULT NULL,
`Ssex` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of student
-- ----------------------------
INSERT INTO `student` VALUES ('01', '赵雷', '1990-01-01 00:00:00', '男');
INSERT INTO `student` VALUES ('02', '钱电', '1990-12-21 00:00:00', '男');
INSERT INTO `student` VALUES ('03', '孙风', '1990-12-20 00:00:00', '男');
INSERT INTO `student` VALUES ('04', '李云', '1990-12-06 00:00:00', '男');
INSERT INTO `student` VALUES ('05', '周梅', '1991-12-01 00:00:00', '女');
INSERT INTO `student` VALUES ('06', '吴兰', '1992-01-01 00:00:00', '女');
INSERT INTO `student` VALUES ('07', '郑竹', '1989-01-01 00:00:00', '女');
INSERT INTO `student` VALUES ('09', '张三', '2017-12-20 00:00:00', '女');
INSERT INTO `student` VALUES ('10', '李四', '2017-12-25 00:00:00', '女');
INSERT INTO `student` VALUES ('11', '李四', '2012-06-06 00:00:00', '女');
INSERT INTO `student` VALUES ('12', '赵六', '2013-06-13 00:00:00', '女');
INSERT INTO `student` VALUES ('13', '孙七', '2014-06-01 00:00:00', '女');
-- ----------------------------
-- Table structure for teacher
-- ----------------------------
DROP TABLE IF EXISTS `teacher`;
CREATE TABLE `teacher` (
`TId` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`Tname` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of teacher
-- ----------------------------
INSERT INTO `teacher` VALUES ('01', '张三');
INSERT INTO `teacher` VALUES ('02', '李四');
INSERT INTO `teacher` VALUES ('03', '王五');
SET FOREIGN_KEY_CHECKS = 1;
MYSQL经典五十题:
1.查询" 01 “课程比” 02 "课程成绩高的学生的信息及课程分数
SELECT
a.*,
b.score AS score1,
c.score AS score2
FROM
student AS a
LEFT JOIN sc AS b ON a.SId = b.SId
AND b.CId = '01'
LEFT JOIN sc AS c ON a.SId = c.SId
AND c.CId = '02'
WHERE
b.score > c.score
2.查询同时存在" 01 “课程和” 02 "课程的情况
SELECT a.*
FROM student AS a
WHERE a.SId IN (
SELECT SId FROM sc WHERE CId = '01'
) AND a.SId IN (
SELECT SId FROM sc WHERE CId = '02'
);
3.查询存在" 01 “课程但可能不存在” 02 "课程的情况(不存在时显示为 null )
SELECT
a.*,
b.score AS score1,
c.score AS score2
FROM
student AS a
LEFT JOIN sc AS b ON a.SId = b.SId
AND b.CId = '01'
LEFT JOIN sc AS c ON a.SId = c.SId
AND c.CId = '02'
WHERE b.score IS NOT NULL
4.查询不存在" 01 “课程但存在” 02 "课程的情况
SELECT
a.*,
b.score AS score1,
c.score AS score2
FROM
student AS a
LEFT JOIN sc AS b ON a.SId = b.SId
AND b.CId = '01'
LEFT JOIN sc AS c ON a.SId = c.SId
AND c.CId = '02'
WHERE b.score is NULL
and c.score is NOT NULL
5.查询平均成绩⼤于等于 60 分的同学的学生编号和学生姓名和平均成绩
ROUND函数可以放sum avg HAVING放在分组之后
SELECT b.SId, b.Sname, ROUND(AVG(a.score), 2) AS avg_score
FROM sc AS a
LEFT JOIN student AS b ON a.SId = b.SId
GROUP BY b.SId, b.Sname
HAVING avg_score > 60;
6.查询在 SC 表存在成绩的学生信息
SELECT * FROM student as a
WHERE a.SId in (SELECT DISTINCT SId FROM sc WHERE score is not NULL)
7.查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩,没成绩的显示为 null
SELECT a.SId,a.Sname, COUNT(b.CId), ROUND(SUM(b.score), 2)
FROM student AS a
LEFT JOIN sc AS b ON a.SId = b.SId
GROUP BY a.SId,a.Sname
8.查询「李」姓老师的数量
SELECT COUNT(1) FROM teacher
WHERE Tname LIKE '李%'
9.查询学过「张三」老师授课的同学的信息
SELECT * FROM student
WHERE SId IN(SELECT c.SId FROM teacher as a
LEFT JOIN course as b on a.TId = b.TId
left JOIN sc as c ON b.CId = c.CId
WHERE
a.Tname = '张三')
10.查询没有学全所有课程的同学的信息
SELECT a.*
FROM student AS a
LEFT JOIN (
SELECT SId, COUNT(DISTINCT CId) AS total_courses
FROM sc
GROUP BY SId
) AS b ON a.SId = b.SId
LEFT JOIN (
SELECT COUNT(DISTINCT CId) AS total_courses_all
FROM course
) AS c ON 1=1
WHERE b.total_courses < c.total_courses_all OR b.total_courses IS NULL;
11.查询至少有一门课与学号为" 01 "的同学所学相同的同学的信息
SELECT DISTINCT a.SId,COUNT(a.CId) FROM sc as a
left JOIN student as b ON a.SId = b.SId
WHERE CId IN (SELECT CId FROM sc as a
WHERE a.SId = '01'
) and b.SId != '01'
GROUP BY b.SId
12.查询和" 01 "号的同学学习的课程 完全相同的其他同学的信息 NOT
SELECT DISTINCT b.*
FROM sc AS a
LEFT JOIN student AS b ON a.SId = b.SId
WHERE b.SId != '01'
AND NOT EXISTS (
SELECT CId
FROM sc
WHERE SId = '01'
EXCEPT
SELECT CId
FROM sc
WHERE SId = b.SId
)
AND NOT EXISTS (
SELECT CId
FROM sc
WHERE SId = b.SId
EXCEPT
SELECT CId
FROM sc
WHERE SId = '01'
);
13.查询没学过"张三"老师讲授的任一门课程的学生姓名
SELECT DISTINCT s.Sname
FROM student AS s
WHERE s.SId NOT IN (
SELECT c.SId
FROM teacher AS t
LEFT JOIN course AS b ON t.TId = b.TId
LEFT JOIN sc AS c ON b.CId = c.CId
WHERE t.Tname = '张三'
);
14.查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩
SELECT b.SId, b.Sname,
ROUND(AVG(a.Score), 2) AS average_score,
SUM(CASE WHEN a.Score < 60 THEN 1 ELSE 0 END) AS num_failures
FROM sc AS a
LEFT JOIN student AS b ON a.SId = b.SId
GROUP BY b.SId, b.Sname
HAVING num_failures >= 2;
15.检索" 01 "课程分数小于 60,按分数降序排列的学生信息
SELECT b.*,a.score FROM sc as a
LEFT JOIN student as b on a.SId = b.SId
WHERE a.CId = '01'
ORDER BY a.score DESC
16.按平均成绩从⾼到低显示所有学生的所有课程的成绩以及平均成绩
SELECT c.SId,
c.avg,
d.score as 语文,
e.score as 数学,
f.score as 英语
FROM
(
SELECT ROUND(AVG(a.Score), 2) AS avg, a.SId
FROM sc AS a
GROUP BY a.SId
) AS c
LEFT JOIN (SELECT score,SId FROM sc WHERE CId = '01') as d ON c.SId = d.SId
LEFT JOIN (SELECT score,SId FROM sc WHERE CId = '02') as e ON c.SId = e.SId
LEFT JOIN (SELECT score,SId FROM sc WHERE CId = '03') as f ON c.SId = f.SId
ORDER BY c.avg DESC
17.查询各科成绩最⾼分、最低分和平均分: 以如下形式显示:课程 ID,课程 name,最⾼分,最低分,平均分,及格率,中等率,优良率,优秀率 及格为>=60,中等为:70-80,优良为:80-90,优秀为:>=90要求输出课程号和选修人数,查询结果按人数降序排列,若人数相同,按课程号升序排列
SELECT
a.CId,
b.Cname,
MAX( score ) AS 最高分,
MIN( score ) AS 最低分,
ROUND(AVG(score),2) AS 平均分,
ROUND( SUM( CASE WHEN score >= 60 THEN 1 ELSE 0 END )/ COUNT( a.CId ), 2 ) AS 及格率,
ROUND( SUM( CASE WHEN score >= 70 AND score < 80 THEN 1 ELSE 0 END )/ COUNT( a.CId ), 2 ) AS 中等率,
ROUND( SUM( CASE WHEN score >= 80 AND score < 90 THEN 1 ELSE 0 END )/ COUNT( a.CId ), 2 ) AS 优良率,
ROUND( SUM( CASE WHEN score >= 90 THEN 1 ELSE 0 END )/ COUNT( a.CId ), 2 ) AS 优秀 ,
COUNT(a.CId) AS 选修人数
FROM
sc as a LEFT JOIN course AS b
ON a.CId = b.CId
GROUP BY
a.CId,b.Cname
ORDER BY COUNT(a.CId),a.CId
18.按各科平均成绩进行排序,并显示排名
SELECT
a.CId,
b.Cname,
ROUND(AVG(score),2) AS 平均分
FROM
sc as a LEFT JOIN course AS b
ON a.CId = b.CId
GROUP BY
a.CId,b.Cname
ORDER BY ROUND(AVG(score),2) DESC
19.按各科平均成绩进行排序,并显示排名,重复时不保留名次空缺
SET @i :=0;-- 定义一个变量
SELECT
c.CId,
c.Cname,
c.avg AS 平均分,
@i := @i + 1 AS '排名'
FROM
(
SELECT
a.CId,
b.Cname,
ROUND(AVG(score),2) AS avg
FROM
sc as a LEFT JOIN course AS b
ON a.CId = b.CId
GROUP BY
a.CId,b.Cname
ORDER BY ROUND(AVG(score),2) ASC
) as c
20.查询学生的总成绩,并进行排名,总分重复时保留名次空缺
SELECT
c.SId,
c.Sname,
c.sum AS 总成绩,
@i := @i + 1 AS '排名'
FROM
(
SELECT
a.SId,
b.Sname,
ROUND(SUM(score),2) AS sum
FROM
sc as a LEFT JOIN student AS b
ON a.SId = b.SId
GROUP BY
a.SId,b.Sname
ORDER BY sum DESC
) as c
22.统计各科成绩各分数段人数:课程编号,课程名称,[100-85),[85-70),[70-60),[60-0)及所占百分
SELECT
a.CId,
b.Cname,
ROUND( sum( CASE WHEN score >= 85 AND score < 100 THEN 1 ELSE 0 END ), 2 )/COUNT(SId) AS 优秀,
ROUND( sum( CASE WHEN score >= 70 AND score < 85 THEN 1 ELSE 0 END ), 2 )/COUNT(SId) AS 优良,
ROUND( sum( CASE WHEN score >= 60 AND score < 70 THEN 1 ELSE 0 END ), 2 ) /COUNT(SId)AS 及格,
ROUND( sum( CASE WHEN score >= 0 AND score < 60 THEN 1 ELSE 0 END ), 2 ) /COUNT(SId)AS 不及格
FROM
sc as a LEFT JOIN course AS b
ON a.CId = b.CId
GROUP BY
a.CId,b.Cname
ORDER BY COUNT(a.CId),a.CId
23.查询各科成绩前三名的记录
PARTITION BY CId 按照CId分组 ORDER BY score DESC 按照分数排序
SELECT * FROM (
SELECT
*,
ROW_NUMBER() OVER(PARTITION BY CId ORDER BY score DESC) AS ranking
FROM sc
) AS ranked_scores
WHERE ranking <= 3;
24.查询每门课程被选修的学生数
SELECT CId,COUNT(CId) FROM sc
GROUP BY CId
25.查询出只选修两门课程的学生学号和姓名
SELECT a.SId,a.Sname,b.count FROM student as a
LEFT JOIN (SELECT SId,COUNT(SId) as count FROM sc
GROUP BY SId) as b ON a.SId = b.SId
WHERE b.count = 2
26.查询男生、女生人数
SELECT Ssex,COUNT(SId) FROM student
GROUP BY Ssex
27.查询名字中含有「风」字的学生信息
SELECT * FROM student
WHERE Sname LIKE '%风%'
28.查询同名同性学生名单,并统计同名同性人数
SELECT Sname,COUNT(Sname) as count FROM student
GROUP BY Sname
HAVING count > 1
29.查询 1990 年出生的学生名单
SELECT * FROM student
WHERE Sage like '1990%'
30.查询每门课程的平均成绩,结果按平均成绩降序排列,平均成绩相同时,按课程编号升序排列
SELECT CId,ROUND(AVG(score),2) as avg FROM sc
GROUP BY CId
ORDER BY avg DESC,CId
31.查询平均成绩大于等于 85 的所有学生的学号、姓名和平均成绩
SELECT
sc.SId,
ROUND( SUM( sc.score )/ COUNT( sc.score ), 2 ) AS num,
b.Sname
FROM
sc
LEFT JOIN student AS b ON sc.SId = b.SId
GROUP BY
sc.SId , b.Sname
HAVING
num >= 85
32.查询课程名称为「数学」,且分数低于 60 的学生姓名和分数
SELECT c.SId,c.Sname,b.score FROM course as a
LEFT JOIN sc as b ON a.CId = b.CId
LEFT JOIN student as c ON b.SId = c.SId
WHERE a.Cname = '数学' and b.score < 60
33.查询所有学生的课程及分数情况(存在学生没成绩,没选课的情况)
SELECT c.SId,c.Sname,b.`语文`,b.`英语`,b.`数学` FROM student as c
LEFT JOIN (SELECT a.SId,
SUM(CASE CId WHEN '01' THEN score ELSE 0 END) AS '语文',
SUM(CASE CId WHEN '02' THEN score ELSE 0 END) AS '数学',
SUM(CASE CId WHEN '03' THEN score ELSE 0 END) AS '英语'
FROM student as a
LEFT JOIN sc as b ON a.SId = b.SId
GROUP BY SId) as b ON c.SId = b.SId
34.查询任何一门课程成绩在 70 分以上的姓名、课程名称和分数
SELECT b.Cname,c.Sname,a.score FROM sc as a
LEFT JOIN course as b ON a.CId = b.CId
LEFT JOIN student as c ON a.SId = c.SId
WHERE a.score >70
35.查询不及格的课程
SELECT b.Cname,c.Sname,a.score FROM sc as a
LEFT JOIN course as b ON a.CId = b.CId
LEFT JOIN student as c ON a.SId = c.SId
WHERE a.score < 60
36.查询课程编号为 01 且课程成绩在 80 分以上的学生的学号和姓名
SELECT
a.SId,
a.Sname,
b.score
FROM
student AS a
INNER JOIN ( SELECT * FROM sc WHERE CId = '01' AND score >= '80' ) AS b ON a.SId = b.SId
37.求每门课程的学生人数
SELECT CId,COUNT(CId) as total FROM sc
GROUP BY CId
38.成绩不重复,查询选修「张三」老师所授课程的学生中,成绩最高的学生信息及其成绩
SELECT d.*,c.score FROM teacher a
LEFT JOIN course as b ON a.TId = b.TId
LEFT JOIN sc as c ON b.CId = c.CId
LEFT JOIN student AS d ON c.SId = d.SId
WHERE
a.Tname = '张三'
ORDER BY c.score DESC
LIMIT 1
40.查询不同课程成绩相同的学生的学生编号、课程编号、学生成绩
SELECT sc.SId, sc.CId, sc.score
FROM sc
JOIN (
SELECT SId, score
FROM sc
GROUP BY SId, score
HAVING COUNT(DISTINCT CId) > 1
) AS same_scores ON sc.SId = same_scores.SId AND sc.score = same_scores.score;
42.统计每门课程的学生选修人数(超过 5 人的课程才统计)
SELECT CId,COUNT(CId) as total FROM sc
GROUP BY CId
HAVING total > 5
43.检索至少选修两门课程的学生学号
SELECT SId,COUNT(SId) as total FROM sc
GROUP BY SId
HAVING total > 2
44.查询选修了全部课程的学生信息
SELECT a.* FROM student as a
WHERE SId IN(SELECT SId FROM sc a
GROUP BY SId
HAVING COUNT(SId) = (SELECT COUNT(*) FROM course))
45.查询各学生的年龄,只按年份来算
SELECT Sname,TIMESTAMPDIFF(YEAR, Sage, NOW()) AS 年龄
FROM student;
46.按照出生日期来算,当前月日 < 出生年月的月日,则年龄减一
SELECT Sname,
CASE
WHEN MONTH(Sage) < MONTH(NOW()) THEN
(TIMESTAMPDIFF(YEAR, Sage, NOW()) - 1)
ELSE
TIMESTAMPDIFF(YEAR, Sage, NOW())
END as age
FROM student
47.查询本周过生日的学生
SELECT *
FROM student
WHERE WEEK(Sage) = WEEK(NOW())
48.查询下周过生日的学生
SELECT *
FROM student
WHERE WEEK(Sage) = WEEK(date_add(now(),INTERVAL 1 WEEK));
49.查询本月过生日的学生
SELECT *,MONTH(Sage)
FROM student
WHERE MONTH(Sage) = MONTH(NOW())
50.查询下月过生日的学生
SELECT *,MONTH(Sage)
FROM student
WHERE MONTH(Sage) = MONTH(date_add(now(),INTERVAL 1 MONTH));