MySQL经典练习50题(上)(解析版)
所有笔记、生活分享首发于个人博客
想要获得最佳的阅读体验(无广告且清爽),请访问本篇笔记
MySQL经典练习50题(上)
创建数据库和表
-- 建 表
-- 学 生 表
CREATE TABLE `Student`(
`s_id` VARCHAR(20),
`s_name` VARCHAR(20) NOT NULL DEFAULT '',
`s_birth` VARCHAR(20) NOT NULL DEFAULT '',
`s_sex` VARCHAR(10) NOT NULL DEFAULT '',
PRIMARY KEY(`s_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`)
);
-- 教师表
CREATE TABLE `Teacher`(
`t_id` VARCHAR(20),
`t_name` VARCHAR(20) NOT NULL DEFAULT '',
PRIMARY KEY(`t_id`)
);
-- 成绩表
CREATE TABLE `Score`(
`s_id` VARCHAR(20),
`c_id` VARCHAR(20),
`s_score` INT(3),
PRIMARY KEY(`s_id`,`c_id`)
);-- 插 入 学 生 表 测 试 数 据
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);
表关系
经典50题
查询"01"课程比"02"课程成绩高的学生的信息及课程分数
select s.*,sc1.s_score,sc2.s_score
from student s
join score sc1 on s.s_id=sc1.s_id and sc1.c_id='01'
join score sc2 on s.s_id=sc2.s_id and sc2.c_id='02'
where sc1.s_score>sc2.s_score
需要连接 student 和 score 表,其中 score 表需要连接两次,因为我们需要对比两个课程的成绩。
然后,这将返回一个结果集,其中每一行都包含学生的信息,以及他们对应的 “01” 课程和 “02” 课程的成绩。但是,我们仍然需要进一步筛选那些 “01” 课程比 “02” 课程成绩高的学生。为此,我们需要在 WHERE 子句中添加一个条件
查询“01”课程比“02”课程成绩低的学生的信息及课程分数(题目 1 是成绩高)
select s.*,sc1.s_score,sc2.s_score
from student s
join score sc1 on s.s_id=sc1.s_id and sc1.c_id='01'
join score sc2 on s.s_id=sc2.s_id and sc2.c_id='02'
where sc1.s_score<sc2.s_score
同上
查询平均成绩大于等于 60 分的同学的学生编号和学生姓名和平均成绩
SELECT s.s_id, s.s_name, AVG(sc.s_score) AS avg_score
FROM student s
LEFT JOIN score sc ON s.s_id = sc.s_id
GROUP BY s.s_id
HAVING avg_score >= 60;
先group by分组再用 having过滤
- 连接两个表 student 和 score 表,使用 JOIN 连接, score 表中要和同学表关联。
- 对学生编号进行分组。
- 计算每位学生的平均成绩。
- 筛选出平均成绩大于等于 60 分的学生
查询平均成绩小于 60 分的同学的学生编号和学生姓名和平均成绩(包括有成绩的和无成绩的)
SELECT s.s_id, s.s_name, AVG(IFNULL(sc.s_score, 0)) AS avg_score
FROM student s
LEFT JOIN score sc ON s.s_id = sc.s_id
GROUP BY s.s_id
HAVING avg_score < 60;
ROUND 函数,用于把数值字段舍入为指定的小数位数。
IFNULL 函数是 MySQL 控制流函数之一,它接受两个参数,如果不是 NULL,则返回第一个参数。 否则,IFNULL 函数返回第二个参数。 两个参数可以是文字值或表达式。
- 从 student 表中查询学生编号和学生姓名,使用 LEFT JOIN 连接 score 表,因为有些学生可能没有成绩记录,使用 LEFT JOIN 可以保证这些学生也能被查询到。
- 使用 IFNULL 函数将无成绩的记录的成绩值设为 0,这样可以保证所有学生都有成绩值。
- 使用 AVG 函数计算每个学生的平均成绩。
- 使用 GROUP BY 对学生编号进行分组,以便计算每个学生的平均成绩。
- 使用 HAVING 过滤出平均成绩小于 60 分的学生。
查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩
SELECT s.s_id, s.s_name, COUNT(sc.c_id) AS course_count, SUM(sc.s_score) AS total_score
FROM student s
LEFT JOIN score sc ON s.s_id = sc.s_id
GROUP BY s.s_id, s.s_name;
- 从 student 表中查询学生编号和学生姓名,使用 LEFT JOIN 连接 score 表,因为有些学生可能没有选课记录,使用 LEFT JOIN 可以保证这些学生也能被查询到。
- 使用 COUNT 函数计算每个学生的选课总数。
- 使用 SUM 函数计算每个学生所有课程的总成绩。
- 使用 GROUP BY 对学生编号和学生姓名进行分组,以便计算每个学生的选课总数和所有课程的总成绩。
查询”李”姓老师的数量
SELECT COUNT(*) as cnt_name_li
FROM teacher
WHERE t_name like "李%"
- 从 teacher 表中查询所有老师的信息。
- 使用 WHERE 子句过滤出姓”李”的老师,使用 LIKE 运算符和通配符%实现模糊匹配。
- 使用 COUNT 函数计算符合条件的老师数量。
COUNT()函数只计算非 NULL 值,如果要计算 NULL 值,可以使用 COUNT(*)
查询学过”张三”老师授课的同学的信息
SELECT s.*, t.t_name
FROM student s
LEFT JOIN score sc ON s.s_id = sc.s_id
LEFT JOIN course co ON sc.c_id = co.c_id
LEFT JOIN teacher t ON co.c_id = t.t_id
WHERE t.t_name = '张三'
就是字面意思
查询没学过”张三”老师授课的同学的信息
## 查询没学过"张三"老师授课的同学的信息
SELECT s.*
FROM student s
WHERE s.s_id NOT IN (SELECT DISTINCT s.s_idFROM student sINNER JOIN score sc ON s.s_id = sc.s_idINNER JOIN course c ON sc.c_id = c.c_idINNER JOIN teacher t ON c.t_id = t.t_idWHERE t.t_name = '张三'
)
- 从 student 表中查询学生的信息。
- 使用子查询查询学过”张三”老师授课的同学的信息。
- 在子查询中,使用 INNER JOIN 连接 score 表、course 表和 teacher 表,以便查询学过”张三”老师授课的课程的学生信息。
- 使用 DISTINCT 关键字去重,以便查询不重复的学生信息。
- 使用 NOT IN 子句过滤出没学过”张三”老师授课的同学的信息。
- 最终查询结果包括学生的学号和姓名。
查询学过编号为”01”并且也学过编号为”02”的课程的同学的信息
SELECT s.*
FROM student s
INNER JOIN score sc1 ON s.s_id = sc1.s_id AND sc1.c_id = '01'
INNER JOIN score sc2 ON s.s_id = sc2.s_id AND sc2.c_id = '02';
- 从 student 表中查询学生的信息。
- 使用 INNER JOIN 连接 score 表两次,以便查询学过编号为”01”和”02”的课程的学生信息。
- 在第一次 INNER JOIN 中,使用 AND 条件将学生 ID 和课程 ID 进行连接。
- 在第二次 INNER JOIN 中,使用 AND 条件将学生 ID 和课程 ID 进行连接。
- 最终查询结果包括学生的学号和姓名
查询学过编号为”01”但是没有学过编号为”02”的课程的同学的信息
SELECT s.*,sc1.c_id sc1,sc2.c_id sc2
FROM student s
INNER JOIN score sc1 ON s.s_id = sc1.s_id AND sc1.c_id = '01'
LEFT JOIN score sc2 ON s.s_id = sc2.s_id AND sc2.c_id = '02'
WHERE sc2.c_id IS NULL;
- 从 student 表中查询学生的信息。
- 使用 INNER JOIN 连接 score 表,以便查询学过编号为”01”的课程的学生信息。
- 在 INNER JOIN 中,使用 AND 条件将学生 ID 和课程 ID 进行连接。
- 使用 LEFT JOIN 连接 score 表,以便查询没学过编号为”02”的课程的学生信息。
- 在 LEFT JOIN 中,使用 AND 条件将学生 ID 和课程 ID 进行连接。
- 使用 WHERE 子句过滤出没学过编号为”02”的课程的学生信息,即 sc2.c_id 为 NULL 的学生信息。
- 最终查询结果包括学生的学号和姓名。
查询没有学完全部课程的同学的信息
SELECT s.*,count(*) AS cs_count
FROM student s
LEFT JOIN score sc ON s.s_id=sc.s_id
GROUP BY s.s_id
HAVING COUNT(DISTINCT sc.c_id)<(SELECT COUNT(*) FROM course)
GROUP BY 筛选 HAVING 过滤出选课数量小于总课程数的人
查询至少有一门课与学号为”01”的同学所学相同的其他同学的信息
SELECT DISTINCT s.s_id, s.s_name
FROM student s
INNER JOIN score sc ON s.s_id = sc.s_id
WHERE s.s_id <> '01' AND sc.c_id IN
(SELECT c_id FROM score WHERE s_id = '01'
);
首先,找到学号为”01”的同学所选修的课程 ID(c_id)。通过 score 表,查询学号为”01”的同学所学的所有课程 ID。
接下来,找到除了学号为”01”的同学之外,选修了上述查询结果中课程 ID 的其他同学。通过 score 表和 student 表的联结,查询选修了与学号为”01”的同学所学相同课程的其他同学的学生 ID(s_id)。
补充:
s.s_id <> ‘01’表示查询条件,其中<>表示不等于的意思。所以 s.s_id <> ‘01’的意思是要筛选出学生 ID(s_id)不等于’01’的学生。换句话说,它将排除学号为’01’的同学,以保证查询结果只包括除了学号为’01’的同学之外的其他同学的信息
查询和”01”号的同学学习的课程完全相同的其他同学的信息
SELECT *
FROM studentWHERE s_id IN (SELECT s_idFROM scoreWHERE s_id != 1AND c_id IN (SELECT c_id FROM score WHERE s_id = 1)GROUP BY s_idHAVING COUNT(c_id) = (SELECT COUNT(c_id) FROM score WHERE s_id = 1)
)
- student 表和 score 表自我连接,得到所有学生的学号和选课信息。
- 对于学号为”01”的学生,筛选出它所选修的课程信息。
- 排除学号为”01”的学生,得到其他学生的学号和选课信息。
- 将其他学生和”01”学生的选课信息进行匹配,得到和”01”学生选课完全相同的其他学生。
- 对这些学生的信息进行聚合,通过计数器比较这些学生选课的数量是否和”01”学生的一致,得到和”01”学生选课完全相同的其他学生的信息
查询没学过”张三”老师讲授的任一门课程的学生姓名
SELECT stu.s_name
FROM student stu
WHERE stu.s_id NOT IN (SELECT sc.c_idFROM score scINNER JOIN course co on sc.c_id = co.c_idINNER JOIN teacher t on co.t_id = t.t_idWHERE t_name = '张三'
)
- 子查询中,通过 INNER JOIN 将 score、course 和 teacher 三个表连接起来,找到所有由”张三”老师讲授的课程对应的学生编号。
- 在主查询中,使用 NOT IN 语句找到所有没有在子查询中出现过的学生编号。
- 最终查询结果中,只包含学生姓名,而不包含其他信息
查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩
SELECT s.s_id, s.s_name, AVG(sc.s_score) as avg_score
FROM student s INNER JOIN score sc ON s.s_id = sc.s_id
WHERE sc.s_score < 60
GROUP BY s.s_id, s.s_name
HAVING COUNT(sc.s_id) >= 2;
1.先使用 JOIN 连接了 student 表和 score 表,以便进行跨表查询。 2.然后使用 WHERE 子句筛选出成绩小于 60 分的记录,代表不及格。 3.接着使用 GROUP BY 对学生的学号和姓名进行分组,方便后续对同一学生的成绩进行平均值计算。 4.最后使用 HAVING 子句筛选出至少有两门不及格课程的学生,并使用 AVG 函数计算出平均成绩。查询结果包括学生的学号、姓名和平均成绩
检索”01”课程分数小于 60,按分数降序排列的学生信息
SELECT s.*,sc.s_score
FROM student s
JOIN score sc ON s.s_id=sc.s_id
WHERE sc.s_score<60 AND sc.c_id = "01"
ORDER BY sc.s_score DESC
- 将学生表和分数表连接
- where 过滤条件
- order by降序输出
按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩
SELECTs.s_id AS 学号,-- 选取学生表 student 中的 s_id 列并将其重命名为 "学号"s.s_name AS 姓名,-- 选取学生表 student 中的 s_name 列并将其重命名为 "姓名"SUM(CASE c_id WHEN 1 THEN s_score ELSE 0 END) AS 语文,-- 计算学生表 student 中的 s_score 列,c_id 为 1 的行数之和,将其命名为 "语文"SUM(CASE c_id WHEN 2 THEN s_score ELSE 0 END) AS 数学,-- 计算学生表 student 中的 s_score 列,c_id 为 2 的行数之和,将其命名为 "数学"SUM(CASE c_id WHEN 3 THEN s_score ELSE 0 END) AS 英语,-- 计算学生表 student 中的 s_score 列,c_id 为 3 的行数之和,将其命名为 "英语"IFNULL(ROUND(AVG(s_score), 2), 0) AS 平均成绩-- 计算学生表 student 中的 s_score 列的平均值,并将结果四舍五入保留两位小数,若结果为 NULL,则返回 0,并将其命名为 "平均成绩"
FROM student s
LEFT JOIN score sc ON s.s_id = sc.s_id
GROUP BY s.s_id, s.s_name
-- 按照学生表 student 中的 s_id,s.s_name 分组
ORDER BY 平均成绩 DESC;
-- 按照 "平均成绩" 列进行降序排序
看注解
CASE …WHEN…THEN…ELSE… 看作是if else叭
将sum与case结合使用,可以实现分段统计
查询各科成绩最高分、最低分和平均分,以如下形式显示
课程 ID,课程 name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率
– 及格为>=60,中等为:70-80,优良为:80-90,优秀为:>=90
selectc.c_id as 课程ID,c.c_name as 课程name,max(s_score) as 最高分,min(s_score) as 最低分,round(avg(s_score), 2) as 平均分,concat(round(sum(case when s_score >= 60 then 1 else 0 end) / count(*) * 100, 2), '%') as 及格率,concat(round(sum(case when s_score between 70 and 80 then 1 else 0 end) / count(*) * 100, 2), '%') as 中等率,concat(round(sum(case when s_score between 80 and 90 then 1 else 0 end) / count(*) * 100, 2), '%') as 优良率,concat(round(sum(case when s_score >= 90 then 1 else 0 end) / count(*) * 100, 2), '%') as 优秀率
from course c
inner join score s on c.c_id = s.c_id
group by c.c_id,c.c_name
concat 表示连接字符的意思
按各科成绩进行排序,并显示排名
SELECT s.s_id,s.s_name,c.c_name,sc.s_score,RANK() OVER (PARTITION BY sc.c_id ORDER BY sc.s_score DESC) AS score_rank
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
ORDER BY c.c_name, score_rank;
SELECT s.s_id, s.s_name, c.c_name, sc.s_score, ...
:选择学生的学号(s.s_id
)、姓名(s.s_name
)、课程名称(c.c_name
)和成绩(sc.s_score
)。RANK() OVER (PARTITION BY sc.c_id ORDER BY sc.s_score DESC) AS score_rank
:使用窗口函数RANK()
来为每个科目的成绩分配排名。PARTITION BY sc.c_id
表示排名是按课程ID分组的,ORDER BY sc.s_score DESC
表示成绩高的排名在前。FROM Student AS s
:指定查询的主表为Student
表,并使用别名s
。JOIN Score AS sc ON s.s_id = sc.s_id
:通过内连接将Student
表和Score
表连接起来,以便能够查询到每个学生的成绩。JOIN Course AS c ON sc.c_id = c.c_id
:通过内连接将Score
表和Course
表连接起来,以便能够查询到课程名称。ORDER BY c.c_name, score_rank
:对查询结果首先按课程名称进行排序,然后按排名排序。这样,每个科目的学生成绩都会按排名顺序显示。
PARTITION BY
是 SQL 中的一个子句,它与窗口函数一起使用,用于指定窗口函数的分区条件。如果需要处理成绩并列的情况,可以将
RANK()
替换为DENSE_RANK()
,这样即使有成绩相同的情况,排名也不会跳过数字
查询学生的总成绩并进行排名
SELECT s.s_name,SUM(IFNULL(sc.s_score,0)) AS '总成绩',
RANK() OVER(ORDER BY SUM(sc.s_score) DESC) AS '排名'
FROM Student s
LEFT JOIN Score sc ON s.s_id=sc.s_id
GROUP BY s.s_name
- SELECT 子句中使用 RANK 函数计算分组排序排名,窗口函数通常会在 ORDER BY 子句中使用。在这个 SQL 语句中,使用 RANK() OVER (ORDER BY SUM(score.s_score) DESC) AS 排名表示对 SUM(score.s_score)的降序排列。
- 通过 JOIN 将 score 表和 student 表连接,获取每个学生的成绩信息和学生姓名。
- 使用 GROUP BY 这个子句将查询结果分组为每个学生,并用 SUM 聚合函数计算每个学生的总分。
查询不同老师所教不同课程平均分从高到低显示
SELECT t.t_name,c.c_name,AVG(sc.s_score) AS"平均分"
FROM teacher t
LEFT JOIN course c ON t.t_id = c.c_id
LEFT JOIN score sc ON c.c_id = sc.c_id
GROUP BY t.t_name,c.c_name
ORDER BY AVG(sc.s_score) DESCs
这个比较简单就没什么好说的
查询所有课程的成绩第 2 名到第 3 名的学生信息及该课程成绩
SELECT student.s_id, student.s_name, student.s_sex, student.s_birth,score.s_score, course.c_name
FROM (SELECT s_id, c_id, s_score,DENSE_RANK() OVER (PARTITION BY c_id ORDER BY s_score DESC) AS `rank`FROM score
) score
JOIN student ON score.s_id = student.s_id
JOIN course ON score.c_id = course.c_id
WHERE score.`rank` BETWEEN 2 AND 3;
- 首先,我们需要为每个学生在每门课程中的成绩计算排名,为此需要使用窗口函数来计算排名。
- 在 SQL 中,计算排名的方法是使用 ROW_NUMBER() 或 DENSE_RANK() 等窗口函数完成。这里我们使用 DENSE_RANK() 函数,该函数按照指定的顺序为每一行分配一个排名号。
- 在计算排名时,注意到需要在每门课程内进行排名,因此我们需要根据课程编号进行分组,这可以使用 PARTITION BY 关键字来实现。
- 对成绩降序排列,这样排名靠前的成绩排在前面,方便后面筛选排名信息。
- 完成为每门课程内学生成绩的排名计算。
- 接下来,我们需要将排名和学生信息、课程信息进行 JOIN,以便查询出每个学生的详细信息和其在课程中的排名情况。
- 最后,我们需要在上述 SQL 语句基础上增加 WHERE 子句,筛选出排名在第二名和第三名的学生记录
统计各科成绩各分数段人数:课程编号,课程名称,[100-85],[85-70],[70-60],[0-60]及所占百分比
SELECTcourse.c_id, course.c_name,COUNT(IF(s_score BETWEEN 85 AND 100, 1, NULL)) AS '100-85',COUNT(IF(s_score BETWEEN 70 AND 84, 1, NULL)) AS '85-70',COUNT(IF(s_score BETWEEN 60 AND 69, 1, NULL)) AS '70-60',COUNT(IF(s_score BETWEEN 0 AND 59, 1, NULL)) AS '0-60',CONCAT(ROUND(COUNT(IF(s_score BETWEEN 85 AND 100, 1, NULL)) / COUNT(*) * 100, 2), '%') AS '100-85(%)',CONCAT(ROUND(COUNT(IF(s_score BETWEEN 70 AND 84, 1, NULL)) / COUNT(*) * 100, 2), '%') AS '85-70(%)',CONCAT(ROUND(COUNT(IF(s_score BETWEEN 60 AND 69, 1, NULL)) / COUNT(*) * 100, 2), '%') AS '70-60(%)',CONCAT(ROUND(COUNT(IF(s_score BETWEEN 0 AND 59, 1, NULL)) / COUNT(*) * 100, 2), '%') AS '0-60(%)'
FROM course
JOIN score ON course.c_id = score.c_id
GROUP BY course.c_id, course.c_name;
首先,我们需要计算出每门课程中各个分数段(100-85,85-70,70-60,0-60)的学生人数以及每个分数段所占百分比(即分数段的人数占总人数的比例)。这可以通过统计成绩表中不同分数段的学生人数来完成。
为了实现该目标,我们可以使用 IF 函数对每个成绩进行分类,然后将每个分数段中成绩符合要求(如成绩在 85-100 分之间)的学生计数为 1。这样,我们可以通过统计不同成绩分类的总数来获得每个分数段的学生人数。
在查询语句中,我们采用了以下方式统计不同分数段中的学生人数和所占百分比:
- 首先使用 JOIN 连接了学生表(student)、课程表(course)和成绩表(score),按照课程编号进行分组。
- 使用 COUNT 函数和 IF 函数组合的方式来计算各个分数段中成绩符合要求的学生人数,例如:
COUNT(IF(s_score BETWEEN 85 AND 100, 1, NULL)) AS '100-85'SQL
该语句用于统计成绩在 85-100 分之间的学生人数,并将统计结果重命名为 “100-85”。
- 将以上计算结果按照课程编号和课程名称进行分组,我们可以获得每门课程中各个分数段的学生人数。
- 使用 ROUND 函数和字符串拼接的方式将每个分数段的百分比表示为一个字符串,这里我们使用 CONCAT 函数对字符串进行拼接,例如:
CONCAT(ROUND(COUNT(IF(s_score BETWEEN 85 AND 100, 1, NULL)) / COUNT(*) * 100, 2), '%') AS '100-85(%)'PLSQL
该语句用于将成绩在 85-100 分之间的学生人数转换为百分比,并将转换结果与一个百分号字符串相拼接,形成最终结果,例如 93.45%。
最终查询结果将包含以下列:课程编号(c_id)、课程名称(c_name)、100-85 分数段内的人数(100-85)、85-70 分数段内的人数(85-70)、70-60 分数段内的人数(70-60)、0-60 分数段内的人数(0-60)、各个分数段所占百分比的字符串表示,例如 12.34%(100-85(%))。
查询学生平均成绩及其名次
SELECT s.s_name,ROUND(AVG(sc.s_score),2) AS '平均成绩',
ROW_NUMBER()OVER(ORDER BY AVG(sc.s_score) DESC) AS '排名'
FROM Student s
LEFT JOIN Score sc ON s.s_id=sc.s_id
GROUP BY s.s_name
连接两张表,求平均成绩、排名
按照姓名分组
查询各科成绩前三名的记录
SELECT r.c_name,r.rank_num,s.s_name,r.s_score
FROM
(SELECT c.c_name,sc.s_id,sc.s_score,
ROW_NUMBER()OVER(PARTITION BY c.c_name ORDER BY sc.s_score DESC) AS rank_num
FROM Course c
LEFT JOIN Score sc ON c.c_id=sc.c_id)r
JOIN Student s ON r.s_id=s.s_id and r.rank_num<=3
- 在子查询中对总成绩倒序排名
- 连接学生表后查询前三名
相关文章:
MySQL经典练习50题(上)(解析版)
所有笔记、生活分享首发于个人博客 想要获得最佳的阅读体验(无广告且清爽),请访问本篇笔记 MySQL经典练习50题(上) 创建数据库和表 -- 建 表 -- 学 生 表 CREATE TABLE Student( s_id VARCHAR(20), s_name VARCHAR(2…...
每日一题33:数据统计之广告效果
一、每日一题 返回结果示例如下: 示例 1: 输入: Ads 表: ------------------------- | ad_id | user_id | action | ------------------------- | 1 | 1 | Clicked | | 2 | 2 | Clicked | | 3 | 3 | Viewed…...
52、有边数限制的最短路
有边数限制的最短路 题目描述 给定一个n个点m条边的有向图,图中可能存在重边和自环, 边权可能为负数。 请你求出从1号点到n号点的最多经过k条边的最短距离,如果无法从1号点走到n号点,输出impossible。 注意:图中可…...
Spring boot实现基于注解的aop面向切面编程
Spring boot实现基于注解的aop面向切面编程 背景 从最开始使用Spring,AOP和IOC的理念就深入我心。正好,我需要写一个基于注解的AOP,被这个注解修饰的参数和属性,就会被拿到参数并校验参数。 一,引入依赖 当前sprin…...
MySQL之查询性能优化(四)
查询性能优化 MySQL客户端/服务器通信协议 一般来说,不需要去理解MySQL通信协议的内部实现细节,只需要大致理解通信协议是如何工作的。MySQL客户端和服务器之间的通信协议是"半双工"的,这意味着,在任何一个时刻&#…...
定时任务详解
文章目录 定时任务详解JDK自带第三方任务调度框架java有哪些定时任务的框架为什么需要定时任务定时任务扫表的方案有什么缺点Quartzxxl-jobxxl-job详解 elastic-job 定时任务详解 在定时任务中,操作系统或应用程序会利用计时器或定时器来定期检查当前时间是否达到了…...
OnlyOffice DocumentServer 8.0.1编译破解版本(¥100)
OnlyOffice DocumentServer 8.0.1编译破解版本(¥100) 破解20人数限制 更换中文字体 修改源码,根据业务自定义服务 根据源码在本机启动项目,便于开发 将编译好的服务打包docker镜像运行 提供各种docker镜像包&…...
Android 应用权限
文章目录 权限声明uses-permissionpermissionpermission-grouppermission-tree其他uses-feature 权限配置 权限声明 Android权限在AndroidManifest.xml中声明,<permission>、 <permission-group> 、<permission-tree> 和<uses-permission>…...
MATLAB 匿名函数
定义匿名函数定义匿名函数的基本语法如下:示例示例 1:简单数学运算示例 2:字符串操作示例 3:作为参数传递 匿名函数的高级用法使用函数句柄定义多输出函数使用局部变量使用嵌套匿名函数 注意事项 匿名函数( Anonymous…...
Java 新手入门:基础知识点一览
Java 新手入门:基础知识点一览 想要踏入 Java 的编程世界?别担心,这篇文章将用简单易懂的表格形式,带你快速了解 Java 的基础知识点。 一、Java 是什么? 概念解释Java一种面向对象的编程语言,拥有跨平台、…...
三维模型轻量化工具:手工模型、BIM、倾斜摄影等皆可用!
老子云是全球领先的数字孪生引擎技术及服务提供商,它专注于让一切3D模型在全网多端轻量化处理与展示,为行业数字化转型升级与数字孪生应用提供成套的3D可视化技术、产品与服务。 老子云是全球领先的数字孪生引擎技术及服务提供商,它专注于让…...
小程序CI/CD之自动化打包预览并钉钉通知发布进程
小程序打包方式分为两种:手动打包、自动打包 那如何实现 自动打包 呐?我们今天就来聊一聊! 首先,很重要,看 官方文档 这里提到今天我们要聊的“主角” miniprogram-ci miniprogram-ci 是从微信开发者工具中抽离的关于…...
C++使用QtHttpServer开发服务端Server的Http POST接口和客户端Client示例
Client HTTP POST 假设http://127.0.0.1:8888/post/是一个能够接受POST请求的路径,我们想要向它提交一段json数据,用Qt可以这样实现: Suppose we want to make an HTTP POST with json body to http://127.0.0.1:8888/post/. QCoreApplica…...
计算机基础(8)——音频数字化(模电与数电)
💗计算机基础系列文章💗 👉🍀计算机基础(1)——计算机的发展史🍀👉🍀计算机基础(2)——冯诺依曼体系结构🍀👉ἴ…...
手搓单链表(无哨兵位)(C语言)
目录 SLT.h SLT.c SLTtest.c 测试示例 单链表优劣分析 SLT.h #pragma once#include <stdio.h> #include <assert.h> #include <stdlib.h>typedef int SLTDataType;typedef struct SListNode {SLTDataType data;struct SListNode* next; }SLTNode;//打印…...
代码随想录算法训练营第18天|二叉树
513. 找树左下角的值 最左边的结点的特性 1.只能是叶子结点, 2.必须考虑是最底层,所以要考虑树的深度 3.同样的深度考虑左子树 考虑迭代法,层序遍历 递归优点难搞的 /*** Definition for a binary tree node.* function TreeNode(val, left, righ…...
使用tftpd更新开发板内核
我们升级内核可以通过原厂提供的升级软件来进行,比如瑞芯微的RKDevTool.exe,只不过这种方式必须通过指定的OTG升级口,还得借助按键进入loader模式后才可以。 其实还可以利用一些通用的工具来进行升级,比如tftpd工具。 下载地址p…...
MySQL数据库整体知识点简述
目录 第一章:数据库系统概述 第二章:信息与数据模型 第3章 关系模型与关系规范化理论 第四章——数据库设计方法 第六-七章——MySQL存储引擎与数据库操作管理 第九章——索引 第10章——视图 第11章——MySQL存储过程与函数 第12章——MySQL 触…...
深入理解MySQL索引下推优化
在MySQL中,索引的使用对于查询性能至关重要。然而,即使有合适的索引,有时查询性能仍然不尽如人意。索引下推(Index Condition Pushdown,ICP)是一项能够进一步优化查询性能的技术。本文将详细讲解索引下推的…...
论文降重技巧:AI工具如何助力论文原创性提升?
论文降重一直是困扰各界毕业生的“拦路虎”,还不容易熬过修改的苦,又要迎来降重的痛。 其实想要给论文降重达标,我有一些独家秘诀。话不多说直接上干货! 1、同义词改写(针对整段整句重复) 这是最靠谱也是…...
el-date-picker的使用,及解决切换type时面板样式错乱问题
这里选择器的类型可以选择日月年和时间范围,根据类型不同,el-date-picker的面板也展示不同,但是会出现el-date-picker错位,或者面板位置和层级等问题。 源代码: <el-selectv-model"dateType"placeholder&…...
Flutter 中的 ToggleButtonsTheme 小部件:全面指南
Flutter 中的 ToggleButtonsTheme 小部件:全面指南 Flutter,作为由 Google 开发的跨平台 UI 框架,为开发者提供了丰富的组件来构建现代化的应用程序。ToggleButtons 是 Material Design 组件库中的一个组件,它允许用户从一组选项…...
新手教程之使用LLaMa-Factory微调LLaMa3
文章目录 为什么要用LLaMa-Factory什么是LLaMa-FactoryLLaMa-Factory环境搭建微调LLaMA3参考博文 为什么要用LLaMa-Factory 如果你尝试过微调大模型,你就会知道,大模型的环境配置是非常繁琐的,需要安装大量的第三方库和依赖,甚至…...
Java函数笔记
1. Statement.executeQuery 和 Statement.executeUpdate 作用: 用于执行SQL查询和更新操作。 问题: 容易导致SQL注入攻击。 解决方法: 使用PreparedStatement进行参数化查询。 // 不安全的做法 Statement stmt connection.createStat…...
Maven实战: 从工程创建自定义archetype
在上一节中(创建自定义archetype)我们手动创建了一个项目模板,经过5步能创建出一个项目模板,如果我有一个现成的项目,想用这个项目作为模板来生成其他项目呢?Maven提供了基于项目生成archetype模板的能力,我们分3步来讲…...
初识JAVA中的包装类,时间复杂度及空间复杂度
目录: 一.包装类 二.时间复杂度 三.空间复杂度 一.包装类: 在Java中,由于基本类型不是继承自Object,为了在泛型代码中可以支持基本类型,Java 给每个基本类型都对应了一个包装类型。 1 基本数据类型和对应的包装类 &am…...
RapidMiner如何利用Hugging Face中的模型实现更有趣的事
RapidMiner Studio最新发布的功能更新,重点是嵌入Hugging Face和Open AI,Hugging face中含有大量的可用模型,包含翻译、总结、文本生成等等强大的模型,Open AI更不必说了,生成界的鼻祖。那么今天主要介绍一下RapidMine…...
Vue3 自定义Hooks函数的封装
1、如何理解vue3中的自定义hooks 在Vue 3中,自定义hooks允许开发者封装和重用逻辑代码。自定义hooks是使用Composition API时创建的函数,这些函数可以包含任意的组合逻辑,并且可以在多个组件之间共享。 自定义hooks通常遵循这样的命名约定&…...
python的DataFrame和Series
Series、DataFrame 创建 pd.Series() pd.DataFrame() # 字典{列名:[值1,值2],} [[]] [()] numpy Pandas的底层的数据结构,就是numpy的数组 ndarray 常用属性 shape (行数,) (行数,列数) values → ndarray index 索引名 siz…...
ARP欺骗的原理与详细步骤
ARP是什么: 我还记得在计算机网络课程当中,学过ARP协议,ARP是地址转换协议,是链路层的协议,是硬件与上层之间的接口,同时对上层提供服务。在局域网中主机与主机之间不能直接通过IP地址进行通信,…...
哪些网站做的好看的图片/微博营销策略
在jquery中,遍历对象和数组,经常会用到$().each和$.each(),两个方法。两个方法是有区别的,从而这两个方法在针对不同的操作上,显示了各自的特点。 $().each,对于这个方法,在dom处理上面用的较多。如果页面有…...
一站式服务包括哪些内容/查域名的网址
递归这东西真是抽象,我看着看着算法,就囫囵吞枣地的写了下,写得囧了 这次先用递归实现先序,中序,后序遍历算法。先大概说下原理:我输入一大串字符,中间#就是代表了空,基本的储存结构…...
wordpress怎么做积分/市场营销培训
如果你曾用过 Go 中的 goroutines,你也许会遇到几个并发原语,如 sync.Mutex, sync.WaitGroup 或是 sync.Map,但是你听说过 sync.Once 么?也许你听说过,那 go 文档是怎么描述它的呢?Once 是只执行一个操作的…...
加入google广告wordpress/学生个人网页制作成品
在当下这个互联网高速发展时代,很多企业时常会面临软件需求的增加以及开发人员的短缺等问题,所以才得以让低代码开发平台的迅速发展。而且根据今年的状况来看,国内很多企业对于低代码的市场需求也在逐步增加。面对这样的局面,会给…...
南京 网站建设/互联网营销的十五种方式
php结合layui前端实现多图上传前端html代码请选择图片文件名图片预览大小状态操作开始上传js 代码layui.use(upload, function() {var $ layui.jquery,upload layui.upload;//多文件列表示例var demoListView $(#demoList),uploadListIns upload.render({elem: #testList,u…...
做那种英文网站有流量/网络卖货平台有哪些
JDK自带的native2ascii工具完全揭密作者:熔岩日期:2006-12-19MSN :[email]leizhimin126.com[/email]背景:在做Java开发的时候,常常会出现一些乱码,或者无法正确识别或读取的文件,比如常见的vali…...