欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

SQL笔试经典50题及答案解析(题目11-20)

程序员文章站 2022-04-05 17:11:09
...

前言
最近博主在准备数据分析岗位的笔试和面试,其中的考察重点就是SQL。听说练了这50道题目,什么现场手撕SQL统统都不怕,我就赶紧来练习了!壮士们,练完以后就什么都不怕啦~

环境:
Navicat Premium 12

说明:
本篇练习的是题目11-20,都很简单,新手也不用害怕~
题目1-10:
题目21-30:
题目31-40:
题目41-50:

创建表

表说明

本次创建的表有四张:

  • 学生表(student): 包含 学生号,学生姓名,出生年月,性别 四个字段
  • 教师表(teacher): 包含教师号,教师姓名 两个字段
  • 成绩表(sc): 包含学生号,课程号,成绩 三个字段
  • 课程表(course): 包含课程号,课程名,教师号 三个字段

表创建

# 创建学生表
create table Student(sid varchar(10),sname varchar(10),sage datetime,ssex nvarchar(10));
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' , '女');

# 创建课程表
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');


# 创建教师表
create table Teacher(tid varchar(10),tname varchar(10));
insert into Teacher values('01' , '张三');
insert into Teacher values('02' , '李四');
insert into Teacher values('03' , '王五');


# 创建成绩表
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);

表显示

学生表如下:
SQL笔试经典50题及答案解析(题目11-20)
教师表如下:
SQL笔试经典50题及答案解析(题目11-20)
成绩表如下:
SQL笔试经典50题及答案解析(题目11-20)
课程表如下:
SQL笔试经典50题及答案解析(题目11-20)

题目

题目11

查询至少有一门课与学号为“01”的同学所学相同的同学的学号和姓名;

SELECT DISTINCT sc.sid,sname
FROM sc
JOIN student	AS s
ON sc.sid = s.sid
WHERE cid IN 
# 只要其他同学的cid包含在“01”同学的课程里面,就满足至少修了一门一样的课程,这里使用IN就行
	(
	SELECT DISTINCT cid
	FROM sc
	WHERE sid='01'
	)# 找出“01”同学都学了哪些课程,为了避免有些课程有多个成绩(重修),因此这里在cid前面加上DISTINCT

注意事项

  • 考察IN的用法:其实就是在一群值里面搜索

运行结果
SQL笔试经典50题及答案解析(题目11-20)

题目12(重要)

查询和"01"号的同学学习的课程完全相同的其他同学的学号和姓名

SELECT DISTINCT sc.sid,sname
FROM sc
JOIN student AS s
ON sc.sid = s.sid
WHERE sc.sid!= '01' # 查询和01同学一样的,把01同学本人在名单里面排除
AND cid IN
	(
	SELECT DISTINCT cid
	FROM sc
	WHERE sid='01'
	) # 课程内容:在01同学所学课程范围内(排除学了其他课程的同学)
GROUP BY sc.sid 
HAVING COUNT(DISTINCT sc.cid)
=(SELECT COUNT(DISTINCT cid) FROM sc WHERE sid='01') # 课程数量:也要和01同学一样

注意事项

  • 完全相同,意味着既要课程数量相同,又要课程内容相同

运行结果
SQL笔试经典50题及答案解析(题目11-20)

题目13(重要)

把“SC”表中“张三”老师教的课的成绩都更改为此课程的平均成绩;

UPDATE sc
SET score=
(
	SELECT avg_score FROM 
	# 不加这一层会报错:错误提示会说,不能先select出同一表中的某些值,再update这个表(在同一语句中)
	# 解决办法:update的时候注意加上这一层查询就能解决问题了,下面同理
	(
		SELECT AVG(score) AS avg_score
		FROM sc
		LEFT JOIN course AS c ON sc.cid = c.cid
		LEFT JOIN teacher AS t ON c.tid = t.tid
		WHERE t.tname = '张三' # 查询张三老师教的课程的平均成绩
	) AS t1
) 
WHERE cid IN(
	SELECT cid FROM
	(
		SELECT DISTINCT sc.cid FROM sc
		LEFT JOIN course AS c ON sc.cid = c.cid
		LEFT JOIN teacher AS t ON c.tid = t.tid
		WHERE t.tname = '张三'
	) AS t2
)

注意事项

  • UPDATE用法:UPDATE 表名称 SET 列名称 = 新值 [WHERE 列名称 = 某值](方括号里面的语句表示可选)
  • 解题思路:
    • 先算出“张三”老师教的课的成绩的平均成绩
    • 进行update的时候,使用where限定课程教师是张三

运行结果
SQL笔试经典50题及答案解析(题目11-20)
有6行记录被改变了,接下来让我们详细看一下原始数据表:
SQL笔试经典50题及答案解析(题目11-20)

题目14

查询没学过"张三"老师讲授的任一门课程的学生姓名

SELECT DISTINCT sid,sname 
FROM student 
WHERE sid NOT IN
	(SELECT sid
	FROM sc
	LEFT JOIN course AS c ON sc.cid = c.cid
	LEFT JOIN teacher AS t ON c.tid = t.tid
	WHERE	t.tname = '张三')

注意事项

  • 没学过张三老师的课,可以逆向思维进行思考,先选出修过张三老师课程的学生,然后使用NOT IN就可以排除这些学生了

运行结果
SQL笔试经典50题及答案解析(题目11-20)

题目15

查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩

SELECT sc.sid,s.sname,AVG(score) AS avg_score
FROM sc
LEFT JOIN student AS s
ON sc.sid = s.sid
WHERE score<60  # 首先用where把所有不及格的成绩揪出来
GROUP BY sid  # 然后按照学号进行分组
HAVING COUNT(DISTINCT score)>=2  # 最后把有两门及以上不及格的人过滤出来

注意事项

运行结果
SQL笔试经典50题及答案解析(题目11-20)

题目16

检索"01"课程分数小于60,按分数降序排列的学生信息

SELECT sid,cid,score
FROM sc
WHERE cid='01' AND score < 60
ORDER BY score DESC

运行结果
SQL笔试经典50题及答案解析(题目11-20)

题目17

按平均成绩从高到低显示所有学生的平均成绩

SELECT sid,AVG(score) AS avg_score
FROM sc
GROUP BY sid # 按照学号归类,求成绩均值
ORDER BY avg_score desc

运行结果
SQL笔试经典50题及答案解析(题目11-20)

题目18

查询各科成绩最高分、最低分和平均分:以如下形式显示:课程ID,课程name,最高分,最低分,平均分,及格率

方法1:使用sum计数

# 方法1
SELECT 
	sc.cid
	,c.cname
	,MAX(score)
	,MIN(score)
	,AVG(score)
	,sum(IF(score>=60,1,0))/COUNT(score) AS pass_rate #分数大于60记为1,否则记为0,然后求和
FROM sc
LEFT JOIN course AS c ON sc.cid = c.cid
GROUP BY cid

方法2:使用count计数

# 方法2
SELECT 
	sc.cid
	,c.cname
	,MAX(score)
	,MIN(score)
	,AVG(score)
	,COUNT(IF(score>=60,score,NULL))/COUNT(score) AS pass_rate #分数大于60返回score,否则返回null,然后计数
FROM sc
LEFT JOIN course AS c ON sc.cid = c.cid
GROUP BY cid

注意事项

运行结果
SQL笔试经典50题及答案解析(题目11-20)

题目19

按各科平均成绩从低到高和及格率的百分数从高到低顺序

SELECT 
	sc.cid
	,AVG(score)AS avg_score
	,sum(IF(score>=60,1,0))/COUNT(score) AS pass_rate
FROM sc
GROUP BY cid
ORDER BY avg_score ASC,pass_rate DESC # 先按照平均成绩升序排,再按照及格率降序排

注意事项

  • ORDER BY使用的时候,可以按照多个字段进行排序,中间用逗号隔开

运行结果
SQL笔试经典50题及答案解析(题目11-20)

题目20(重要)

查询学生的总成绩并进行排名

方法1:使用自连接

# 方法1
#核心思想:>=60分的有三个,那么60就是第3名;>=某数的值有几个,某数就排第几名
SELECT t1.sid,t1.total_score,COUNT(t2.total_score) AS srank #此处别名不要用rank,会报错
FROM
	(SELECT sid,SUM(score) AS total_score
	FROM sc 
	GROUP BY sid) AS t1 #创建表1,按照学号分组,计算每个学生总分
LEFT JOIN
	(SELECT sid,SUM(score) AS total_score
	FROM sc 
	GROUP BY sid) AS t2 #创建表2,和表1一模一样
ON t1.total_score<=t2.total_score 
#关键操作!记住这个连接条件,对于表1的每一行,在表2中的数据都存在所有>=表1的数据;
GROUP BY t1.total_score
# 然后按照表1的成绩进行分组,对表2的数据计数,这就是排名
ORDER BY t1.total_score DESC

方法2:使用函数rank()

# 方法2
SELECT 
	sid
	,SUM(score) AS total_score
	,rank() over (ORDER BY SUM(score) DESC) AS srank
FROM sc 
GROUP BY sid

注意事项

运行结果
SQL笔试经典50题及答案解析(题目11-20)

相关标签: SQL sql 数据库