数据库学习3:数据库学习入门21-30题(基于MySQL)

SQL面试必会50题123

21.查询不同老师所教不同课程平均分从高到低显示(不重点)

想法一:以课程为主体,求平均分

SELECT a.c_id,b.c_name'课程名',AVG(a.s_score)'平均分'
FROM Score AS a
INNER JOIN Course AS b ON a.c_id = b.c_id
GROUP BY c_id
ORDER BY 平均分 DESC

在这里插入图片描述

想法二:以老师为主体,求平均分

SELECT c.t_id,c.t_name,AVG(a.s_score)'平均分'
FROM Score AS a
INNER JOIN Course AS b ON a.c_id = b.c_id
INNER JOIN Teacher AS c ON b.t_id = c.t_id
GROUP BY t_id,t_name
ORDER BY 平均分 DESC

在这里插入图片描述

22.查询所有课程的成绩第2名到第3名的学生信息及该课程成绩(重要,与25题类似)

利用窗口函数row_number(),构造一张临时表。

CREATE TEMPORARY TABLE temp AS
(
SELECT a.s_id'学号',a.c_id'课程',a.s_score'成绩',b.s_name'姓名',b.s_sex'性别',b.s_birth'生日',
row_number() over(PARTITION BY a.c_id ORDER BY a.s_score DESC)'rank'
FROM Score AS a
INNER JOIN Student AS b ON a.s_id = b.s_id
) -- 临时表

构造临时表语法:CREATE TEMPORARY TABLE 临时表名 AS (SELECT * FROM *)
删除临时表语法: DROP TEMPORARY TABLE 临时表名;

在这里插入图片描述

SELECT temp.学号,temp.姓名,
temp.性别,temp.生日,
temp.课程,temp.成绩,
temp.rank'排名'
FROM temp
WHERE temp.rank IN (2,3)

提取临时表中列时,每一列前面都要带上“临时表名.”

在这里插入图片描述

23.使用分段[100-85],[85-70],[70-60],[<60]来统计各科成绩,分别统计各分数段人数:课程ID和课程名称(重点,与18题类似,CASE WHEN

SUM做计数器:

SELECT b.c_id,b.c_name'姓名',
SUM(CASE WHEN a.s_score >= 85 AND a.s_score <= 100 THEN 1 ELSE 0 END)'[100-85]',
SUM(CASE WHEN a.s_score >= 70 AND a.s_score < 85 THEN 1 ELSE 0 END)'[85-70]',
SUM(CASE WHEN a.s_score >= 60 AND a.s_score < 70 THEN 1 ELSE 0 END)'[70-60]',
SUM(CASE WHEN a.s_score < 60 THEN 1 ELSE 0 END)'[<60]'
FROM Score AS a
INNER JOIN Course AS b ON a.c_id = b.c_id
GROUP BY c_id,c_name

在这里插入图片描述
COUNT做计数器:

SELECT b.c_id,b.c_name'姓名',
COUNT(CASE WHEN a.s_score >= 85 AND a.s_score <= 100 THEN 1 ELSE NULL END)'[100-85]',
COUNT(CASE WHEN a.s_score >= 70 AND a.s_score < 85 THEN 1 ELSE NULL END)'[85-70]',
COUNT(CASE WHEN a.s_score >= 60 AND a.s_score < 70 THEN 1 ELSE NULL END)'[70-60]',
COUNT(CASE WHEN a.s_score < 60 THEN 1 ELSE NULL END)'[<60]'
FROM Score AS a
INNER JOIN Course AS b ON a.c_id = b.c_id
GROUP BY c_id,c_name

COUNT做计数器要注意,CASE WHEN语句中ELSE后面是NULL,如果是0的话,COUNT(0)= 1,而NULL是不计入数的。

24.查询学生平均成绩及其名次(重点,与19题类似)

SELECT s_id'学号',AVG(s_score)'平均分',
rank() over(ORDER BY AVG(s_score) DESC)'平均分排名' 
FROM Score
GROUP BY s_id

若窗口函数over后的括号里没有PARTITION BY,就说明将整张表作为一类来排序。

在这里插入图片描述

25.查询各科成绩前三名的记录(不考虑成绩并列情况)(重点,与22题类似)

CREATE TEMPORARY TABLE temp AS
(
SELECT s_id'学号',c_id'课程',s_score'成绩',
row_number() over(PARTITION BY c_id ORDER BY s_score DESC)'rank'
FROM Score
) -- 临时表

SELECT temp.`课程`,temp.`学号`,temp.`成绩`,temp.rank'排名前三' 
FROM temp
WHERE temp.rank IN (1,2,3)

在这里插入图片描述

26.查询每门课程被选修的学生数(不重点)

SELECT a.c_id,b.c_name'课程名称',COUNT(DISTINCT a.s_id)'选课人数'
FROM Score AS a
INNER JOIN Course AS b ON a.c_id = b.c_id
GROUP BY c_id,c_name

在这里插入图片描述

27.查询出只有两门课程的全部学生的学号和姓名(不重点)

法一

SELECT a.s_id,b.s_name'姓名'
FROM Score AS a
INNER JOIN Student AS b ON a.s_id = b.s_id
GROUP BY s_id,s_name HAVING COUNT(DISTINCT a.c_id) = 2

法二 推荐,性能好

SELECT s_id'学号',s_name'姓名' FROM Student
WHERE s_id IN
(
SELECT s_id FROM Score
GROUP BY s_id HAVING COUNT(DISTINCT c_id) = 2
)

在这里插入图片描述

28.查询男生、女生人数(不重点)

SELECT s_sex'性别',COUNT(DISTINCT s_id) '数目'
FROM Student
GROUP BY s_sex
SELECT s_sex'性别',COUNT(s_sex) '数目' -- 不能加DISTINCT
FROM Student
GROUP BY s_sex

在这里插入图片描述

SELECT
SUM(CASE WHEN s_sex = '男' THEN 1 ELSE 0 END)'男生人数',
SUM(CASE WHEN s_sex = '女' THEN 1 ELSE 0 END)'女生人数'
FROM Student
SELECT
COUNT(CASE WHEN s_sex = '男' THEN 1 ELSE NULL END)'男生人数',
COUNT(CASE WHEN s_sex = '女' THEN 1 ELSE NULL END)'女生人数'
FROM Student

在这里插入图片描述

29.查询名字中含有"风"字的学生信息(不重点)

SELECT s_id'学号',s_name'姓名',s_sex'性别',s_birth'生日'
FROM Student
WHERE s_name LIKE '%风%'

在这里插入图片描述

30题忽略掉


  1. B站视频专栏-up主:陆小亮-【数据分析】- SQL面试50题 - 跟我一起打怪升级 一起成为数据科学家 ↩︎

  2. 知乎-猴子-常见的SQL面试题:经典50题https://zhuanlan.zhihu.com/p/38354000 ↩︎

  3. 知乎-小番茄-SQL面试必会50题https://zhuanlan.zhihu.com/p/43289968 ↩︎

发布了14 篇原创文章 · 获赞 7 · 访问量 3256

猜你喜欢

转载自blog.csdn.net/sunsimiaofromsh/article/details/104616952