SQL语句练习(按难度排序)
★ 难度1:基础查询与简单操作
查询a表中男生所有的信息
1
2
3SELECT 学号, 姓名, 性别, 出生日期, 专业成绩
FROM a
WHERE 性别 = '男';或
1
2
3SELECT *
FROM a
WHERE 性别 = '男';查询a表中男生的姓名和专业成绩
1
2
3SELECT 姓名, 专业成绩
FROM a
WHERE 性别 = '男';查询a表中男生的所有信息并按专业成绩升序排序
1
2
3
4SELECT *
FROM a
WHERE 性别 = '男'
ORDER BY 专业成绩;将a表中学号为“20170105”的学生姓名更改为“孙韬”
1
2
3UPDATE a
SET 姓名 = '孙韬'
WHERE 学号 = '20170105';在a表中插入一条记录:学号:20170106 性别:女 出生日期:2000/09/13 专业成绩:95
1
2INSERT INTO a (学号, 姓名, 性别, 出生日期, 专业成绩)
VALUES ('20170106', '刘芸', '女', '2000-09-13', 95);或
1
2INSERT INTO a
VALUES ('20170106', '刘芸', '女', '2000-09-13', 95);删除a表中学号为“20170101”的记录
1
2DELETE FROM a
WHERE 学号 = '20170101';查询被学号为20170102的学生选修的课程有几个?
1
2
3SELECT COUNT(Cno)
FROM SC
WHERE Sno = '20170102';查询年龄在18~19之间的学生信息
1
2
3SELECT *
FROM S
WHERE age BETWEEN 18 AND 19;查询姓刘的同学的信息
1
2
3SELECT *
FROM S
WHERE Sname LIKE '刘%';查询姓刘且姓名仅仅两字的信息
1
2
3SELECT *
FROM S
WHERE Sname LIKE '刘_';查询没有先修课的课程信息
1
2
3SELECT *
FROM C
WHERE Cpno IS NULL;将女生的年龄减去1岁
1
2
3UPDATE student
SET age = age - 1
WHERE sex = '女';删除200215121学生的选课信息
1
2DELETE FROM SC
WHERE Sno = '200215121';查询课程表的所有信息
1
2SELECT *
FROM 课程表;查询课程名及其学分
1
2SELECT 课程名, 学分
FROM 课程表;查询学生姓名及其出生年份,出生年份的别名为“出生年份”
1
2SELECT 姓名, 出生年份 AS 出生年份
FROM 学生表;
★★ 难度2:分组聚合、子查询与更新
查询a表中男生的姓名和专业成绩,并将查询结果输出到“男生成绩”表
1
2
3
4SELECT 姓名, 专业成绩
INTO 男生成绩
FROM a
WHERE 性别 = '男';按性别统计性别的平均专业成绩
1
2
3SELECT 性别, AVG(专业成绩) AS 平均专业成绩
FROM a
GROUP BY 性别;统计男生的平均专业成绩
1
2
3
4SELECT 性别, AVG(专业成绩) AS 平均专业成绩
FROM a
GROUP BY 性别
HAVING 性别 = '男';查询姓名为张三的学生的选修课程有多少?
1
2
3
4SELECT COUNT(Cno)
FROM SC, S
WHERE Sname = '张三'
AND SC.Sno = S.Sno;或
1
2
3
4
5
6
7SELECT COUNT(Cno)
FROM SC
WHERE Sno IN (
SELECT Sno
FROM S
WHERE Sname = '张三'
);求各门课学生的平均成绩,显示课程号及相应的平均成绩
1
2
3SELECT Cno, AVG(grade)
FROM SC
GROUP BY Cno;查询有2个以上学生选修的课程的课程号
1
2
3
4SELECT Cno
FROM SC
GROUP BY Cno
HAVING COUNT(Sno) > 2;将信息科学系的全体学生成绩设为100分
1
2
3
4
5
6
7UPDATE SC
SET grade = 100
WHERE Sno IN (
SELECT Sno
FROM student
WHERE dept = '信息科学系'
);将成绩表中计算机科学系的学生信息删除
1
2
3
4
5
6DELETE FROM SC
WHERE Sno IN (
SELECT Sno
FROM Student
WHERE Sdept = '计算机科学系'
);查询被学生选修的课程的课程名
1
2
3
4
5
6SELECT DISTINCT 课程名
FROM 课程表
WHERE 课程号 IN (
SELECT DISTINCT 课程号
FROM 成绩表
);查询考试需要补考的学生有几个?
1
2
3SELECT COUNT(DISTINCT 学号)
FROM 成绩表
WHERE 成绩 < 60;查询成绩在90分以上的女生
1
2
3
4
5SELECT DISTINCT 学生表.*
FROM 学生表
JOIN 成绩表 ON 学生表.学号 = 成绩表.学号
WHERE 成绩表.成绩 > 90
AND 学生表.性别 = '女';查询与王敏在一个系学习的学生
1
2
3
4
5
6
7
8SELECT *
FROM 学生表
WHERE 系别 = (
SELECT 系别
FROM 学生表
WHERE 姓名 = '王敏'
)
AND 姓名 != '王敏';
★★★ 难度3:多表连接、视图与复杂条件
查询学生选修课程的情况,要求显示学生名、课程名、成绩
1
2
3
4SELECT Sname, Cname, grade
FROM S, C, SC
WHERE S.Sno = SC.Sno
AND C.Cno = SC.Cno;创建dptg_age,包括两个字段:系别和平均年龄。按系分组求平均年龄,把系名和平均年龄存入新表中,一步完成
1
2
3
4CREATE TABLE dept_age AS
SELECT department AS 系别, AVG(age) AS 平均年龄
FROM student
GROUP BY department;建立视图view_grade,内容为学生姓名、课程名、成绩
1
2
3
4
5
6
7CREATE VIEW view_grade AS
SELECT student.Sname AS 学生姓名,
cource.Cname AS 课程名,
SC.grade AS 成绩
FROM student
JOIN SC ON student.Sno = SC.Sno
JOIN cource ON SC.Cno = cource.Cno;或
1
2
3
4
5
6
7CREATE VIEW view_grade AS
SELECT student.Sname AS 学生姓名,
cource.Cname AS 课程名,
SC.grade AS 成绩
FROM student, cource, sc
WHERE student.Sno = SC.Sno
AND cource.Cno = SC.Cno;查询其他系中比信息系某一学生年龄大的学生姓名和年龄
1
2
3
4
5
6
7
8SELECT 姓名, 年龄
FROM 学生表
WHERE 系别 != '信息系'
AND 年龄 > ANY (
SELECT 年龄
FROM 学生表
WHERE 系别 = '信息系'
);查询其他系中比信息系所有学生年龄大的学生姓名和年龄
1
2
3
4
5
6
7
8SELECT 姓名, 年龄
FROM 学生表
WHERE 系别 != '信息系'
AND 年龄 > ALL (
SELECT 年龄
FROM 学生表
WHERE 系别 = '信息系'
);分别对学生表、成绩表进行:内连接、左外连接、右外连接、全连接
- 内连接:
1
2
3SELECT *
FROM 学生表
INNER JOIN 成绩表 ON 学生表.学号 = 成绩表.学号; - 左外连接:
1
2
3SELECT *
FROM 学生表
LEFT JOIN 成绩表 ON 学生表.学号 = 成绩表.学号; - 右外连接:
1
2
3SELECT *
FROM 学生表
RIGHT JOIN 成绩表 ON 学生表.学号 = 成绩表.学号; - 全连接:
1
2
3SELECT *
FROM 学生表
FULL OUTER JOIN 成绩表 ON 学生表.学号 = 成绩表.学号;
- 内连接:
★★★★ 难度4:高级子查询、窗口函数与复杂逻辑
查询选修了全部课程的学生姓名
1
2
3
4
5
6
7
8
9
10
11
12SELECT Sname
FROM S
WHERE NOT EXISTS (
SELECT *
FROM C
WHERE NOT EXISTS (
SELECT *
FROM SC
WHERE S.Sno = SC.Sno
AND C.Cno = SC.Cno
)
);或
1
2
3
4
5
6
7
8SELECT Sname
FROM S
JOIN SC ON S.Sno = SC.Sno
GROUP BY S.Sno, Sname
HAVING COUNT(DISTINCT Cno) = (
SELECT COUNT(*)
FROM C
);或
1
2
3
4
5
6
7
8
9
10
11SELECT Sname
FROM S
WHERE Sno IN (
SELECT Sno
FROM SC
GROUP BY Sno
HAVING COUNT(DISTINCT Cno) = (
SELECT COUNT(*)
FROM C
)
);查询每门课的间接先修课,要求显示课程名及该课程间接先修课的课程名
1
2
3
4
5SELECT a.课程名, c.课程名 AS 间接先修课名
FROM 课程表 a
LEFT JOIN 课程表 b ON a.先修课号 = b.课程号
LEFT JOIN 课程表 c ON b.先修课号 = c.课程号
WHERE c.课程名 IS NOT NULL;查询被所有学生选修的课程名
1
2
3
4
5
6
7
8
9
10
11SELECT 课程名
FROM 课程表
WHERE 课程号 IN (
SELECT 课程号
FROM 成绩表
GROUP BY 课程号
HAVING COUNT(DISTINCT 学号) = (
SELECT COUNT(*)
FROM 学生表
)
);查询学生成绩5-7名的学生学号、课程号、成绩
1
2
3
4
5
6
7
8
9SELECT 学号, 课程号, 成绩
FROM (
SELECT 学号,
课程号,
成绩,
ROW_NUMBER() OVER (ORDER BY 成绩 DESC) AS rn
FROM 成绩表
) t
WHERE rn BETWEEN 5 AND 7;找出每个学生低于他选修课程平均成绩的课程号
1
2
3
4
5
6
7SELECT 学号, 课程号
FROM 成绩表 a
WHERE 成绩 < (
SELECT AVG(成绩)
FROM 成绩表 b
WHERE b.学号 = a.学号
);
★★★★★ 难度5:关系除法(极值子查询)
- 查询选修了学生95002选修的全部课程的学生学号
1
2
3
4
5
6
7
8
9
10
11
12
13
14SELECT 学号
FROM 学生表
WHERE 学号 != '95002'
AND NOT EXISTS (
SELECT 1
FROM 成绩表 c
WHERE c.学号 = '95002'
AND NOT EXISTS (
SELECT 1
FROM 成绩表 d
WHERE d.学号 = 学生表.学号
AND d.课程号 = c.课程号
)
);
说明:
- 难度分级依据:简单查询(★)、聚合与简单子查询(★★)、多表连接与视图(★★★)、高级子查询与窗口函数(★★★★)、关系除法(★★★★★)。
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 slowbirdie.top@outlook.com