SQL笔试经典50题及答案解析(题目1-10)
程序员文章站
2024-03-15 18:28:24
...
前言
最近博主在准备数据分析岗位的笔试和面试,其中的考察重点就是SQL。听说练了这50道题目,什么现场手撕SQL统统都不怕,我就赶紧来练习了!壮士们,练完以后就什么都不怕啦~
环境:
Navicat Premium 12
说明:
本篇练习的是题目1-:10,都很简单,新手也不用害怕~
题目11-20:
题目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);
表显示
学生表如下:
教师表如下:
成绩表如下:
课程表如下:
题目
题目1
查询“01”课程比“02”课程成绩高的所有学生的学号;
SELECT t1.sid,t1.score,t2.score
FROM
(select sid,score
from sc
where cid = '01') as t1
JOIN
(select sid,score
from sc
where cid = '02') as t2
ON t1.sid = t2.sid and t1.score>t2.score
注意事项:
- 分别找出选修了课程01和课程02的同学,然后join
运行结果:
题目2
查询平均成绩大于60分的同学的学号和平均成绩;
SELECT sid,AVG(score) AS AVG
FROM sc
GROUP BY sid
having avg(score)>60
注意事项:
- 使用group by 和 聚合函数 AVG即可
- 使用group by之后,一定要聚合,max/min/avg/sum/count随便一个都行,如果不聚合,最后显示的结果就是分组内的第一条
运行结果:
题目3
查询所有同学的学号、姓名、选课数、总成绩
SELECT t1.sid,t1.sname,t2.cnt,t2.total_score
FROM
(SELECT sid,sname
FROM student
GROUP BY sid) AS t1
LEFT JOIN
(SELECT sid,COUNT(*) AS cnt,SUM(score) AS total_score
FROM sc
GROUP BY sid) AS t2
ON t1.sid = t2.sid
运行结果:
题目4
查询姓“李”的老师的个数;
SELECT
COUNT( DISTINCT tid ) AS cnt
FROM
teacher
WHERE
tname LIKE '李%'
注意事项:
- 通配符%:表示包含一个或者多个字符
- 通配符_:表示包含一个字符
- 通配符[charlist]:表示包含列表内的任何单一字符
- 通配符[^charlist]或者[! charlist]:表示不包含列表内的任何单一字符
- like:搜索某种模式
运行结果:
题目5
查询没学过“张三”老师课的同学的学号、姓名;
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 = '张三')
注意事项:
- IN 操作符允许我们在 WHERE 子句中规定多个值
运行结果:
题目6
查询学过编号“01”并且也学过编号“02”课程的同学的学号、姓名;(类比题目1)
SELECT DISTINCT sid,sname
FROM student
WHERE sid IN
(
SELECT DISTINCT t1.sid
FROM
(SELECT sid,score
FROM sc
WHERE cid = '01') as t1
JOIN
(SELECT sid,score
FROM sc
WHERE cid = '02') as t2
ON t1.sid = t2.sid
)
注意事项:
- 首先,分别找出选修了课程01和课程02的同学,然后join
- 然后,将上述结果和student表join,就可以得到学生姓名
运行结果:
题目7
查询学过“张三”老师所教的课的同学的学号、姓名;(类比题目5)
SELECT DISTINCT sid,sname
FROM student
WHERE sid 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 = '张三')
运行结果:
题目8
查询课程编号“01”的成绩比课程编号“02”课程低的所有同学的学号、姓名;(类比题目1和题目6)
SELECT DISTINCT s.sid,s.sname
FROM student AS s
JOIN(
SELECT t1.sid
FROM
(SELECT sid,score
FROM sc
WHERE cid = '01') as t1
JOIN
(SELECT sid,score
FROM sc
WHERE cid = '02') as t2
ON t1.sid = t2.sid AND t1.score < t2.score
) t
ON s.sid = t.sid
运行结果:
题目9
查询所有课程成绩小于60分的同学的学号、姓名;
SELECT DISTINCT s.sid,s.sname
FROM student AS s
JOIN(
SELECT sid
FROM sc
GROUP BY sid
HAVING MAX(score) < 60
)AS t
ON s.sid = t.sid
注意事项:
- 所有课程的成绩都小于60份,意味着最大的成绩都小于60分
运行结果:
题目10
查询没有学全所有课的同学的学号、姓名;
SELECT s.sid,s.sname
FROM student AS s
LEFT JOIN sc
on s.sid = sc.sid
GROUP BY s.sid
HAVING COUNT(sc.cid)<3
注意事项:
- 需要先把学生表和成绩表联合,获得所有学生的选课信息,然后再分组计数;
- 只看成绩表,会漏掉没有选课的王菊同学~
运行结果: