SQL语句练习(考试复习)

SQL语句练习(按难度排序)

★ 难度1:基础查询与简单操作

  1. 查询a表中男生所有的信息

    1
    2
    3
    SELECT 学号, 姓名, 性别, 出生日期, 专业成绩
    FROM a
    WHERE 性别 = '男';

    1
    2
    3
    SELECT *
    FROM a
    WHERE 性别 = '男';
  2. 查询a表中男生的姓名和专业成绩

    1
    2
    3
    SELECT 姓名, 专业成绩
    FROM a
    WHERE 性别 = '男';
  3. 查询a表中男生的所有信息并按专业成绩升序排序

    1
    2
    3
    4
    SELECT *
    FROM a
    WHERE 性别 = '男'
    ORDER BY 专业成绩;
  4. 将a表中学号为“20170105”的学生姓名更改为“孙韬”

    1
    2
    3
    UPDATE a
    SET 姓名 = '孙韬'
    WHERE 学号 = '20170105';
  5. 在a表中插入一条记录:学号:20170106 性别:女 出生日期:2000/09/13 专业成绩:95

    1
    2
    INSERT INTO a (学号, 姓名, 性别, 出生日期, 专业成绩)
    VALUES ('20170106', '刘芸', '女', '2000-09-13', 95);

    1
    2
    INSERT INTO a
    VALUES ('20170106', '刘芸', '女', '2000-09-13', 95);
  6. 删除a表中学号为“20170101”的记录

    1
    2
    DELETE FROM a
    WHERE 学号 = '20170101';
  7. 查询被学号为20170102的学生选修的课程有几个?

    1
    2
    3
    SELECT COUNT(Cno)
    FROM SC
    WHERE Sno = '20170102';
  8. 查询年龄在18~19之间的学生信息

    1
    2
    3
    SELECT *
    FROM S
    WHERE age BETWEEN 18 AND 19;
  9. 查询姓刘的同学的信息

    1
    2
    3
    SELECT *
    FROM S
    WHERE Sname LIKE '刘%';
  10. 查询姓刘且姓名仅仅两字的信息

    1
    2
    3
    SELECT *
    FROM S
    WHERE Sname LIKE '刘_';
  11. 查询没有先修课的课程信息

    1
    2
    3
    SELECT *
    FROM C
    WHERE Cpno IS NULL;
  12. 将女生的年龄减去1岁

    1
    2
    3
    UPDATE student
    SET age = age - 1
    WHERE sex = '女';
  13. 删除200215121学生的选课信息

    1
    2
    DELETE FROM SC
    WHERE Sno = '200215121';
  14. 查询课程表的所有信息

    1
    2
    SELECT *
    FROM 课程表;
  15. 查询课程名及其学分

    1
    2
    SELECT 课程名, 学分
    FROM 课程表;
  16. 查询学生姓名及其出生年份,出生年份的别名为“出生年份”

    1
    2
    SELECT 姓名, 出生年份 AS 出生年份
    FROM 学生表;

★★ 难度2:分组聚合、子查询与更新

  1. 查询a表中男生的姓名和专业成绩,并将查询结果输出到“男生成绩”表

    1
    2
    3
    4
    SELECT 姓名, 专业成绩
    INTO 男生成绩
    FROM a
    WHERE 性别 = '男';
  2. 按性别统计性别的平均专业成绩

    1
    2
    3
    SELECT 性别, AVG(专业成绩) AS 平均专业成绩
    FROM a
    GROUP BY 性别;
  3. 统计男生的平均专业成绩

    1
    2
    3
    4
    SELECT 性别, AVG(专业成绩) AS 平均专业成绩
    FROM a
    GROUP BY 性别
    HAVING 性别 = '男';
  4. 查询姓名为张三的学生的选修课程有多少?

    1
    2
    3
    4
    SELECT COUNT(Cno)
    FROM SC, S
    WHERE Sname = '张三'
    AND SC.Sno = S.Sno;

    1
    2
    3
    4
    5
    6
    7
    SELECT COUNT(Cno)
    FROM SC
    WHERE Sno IN (
    SELECT Sno
    FROM S
    WHERE Sname = '张三'
    );
  5. 求各门课学生的平均成绩,显示课程号及相应的平均成绩

    1
    2
    3
    SELECT Cno, AVG(grade)
    FROM SC
    GROUP BY Cno;
  6. 查询有2个以上学生选修的课程的课程号

    1
    2
    3
    4
    SELECT Cno
    FROM SC
    GROUP BY Cno
    HAVING COUNT(Sno) > 2;
  7. 将信息科学系的全体学生成绩设为100分

    1
    2
    3
    4
    5
    6
    7
    UPDATE SC
    SET grade = 100
    WHERE Sno IN (
    SELECT Sno
    FROM student
    WHERE dept = '信息科学系'
    );
  8. 将成绩表中计算机科学系的学生信息删除

    1
    2
    3
    4
    5
    6
    DELETE FROM SC
    WHERE Sno IN (
    SELECT Sno
    FROM Student
    WHERE Sdept = '计算机科学系'
    );
  9. 查询被学生选修的课程的课程名

    1
    2
    3
    4
    5
    6
    SELECT DISTINCT 课程名
    FROM 课程表
    WHERE 课程号 IN (
    SELECT DISTINCT 课程号
    FROM 成绩表
    );
  10. 查询考试需要补考的学生有几个?

    1
    2
    3
    SELECT COUNT(DISTINCT 学号)
    FROM 成绩表
    WHERE 成绩 < 60;
  11. 查询成绩在90分以上的女生

    1
    2
    3
    4
    5
    SELECT DISTINCT 学生表.*
    FROM 学生表
    JOIN 成绩表 ON 学生表.学号 = 成绩表.学号
    WHERE 成绩表.成绩 > 90
    AND 学生表.性别 = '女';
  12. 查询与王敏在一个系学习的学生

    1
    2
    3
    4
    5
    6
    7
    8
    SELECT *
    FROM 学生表
    WHERE 系别 = (
    SELECT 系别
    FROM 学生表
    WHERE 姓名 = '王敏'
    )
    AND 姓名 != '王敏';

★★★ 难度3:多表连接、视图与复杂条件

  1. 查询学生选修课程的情况,要求显示学生名、课程名、成绩

    1
    2
    3
    4
    SELECT Sname, Cname, grade
    FROM S, C, SC
    WHERE S.Sno = SC.Sno
    AND C.Cno = SC.Cno;
  2. 创建dptg_age,包括两个字段:系别和平均年龄。按系分组求平均年龄,把系名和平均年龄存入新表中,一步完成

    1
    2
    3
    4
    CREATE TABLE dept_age AS
    SELECT department AS 系别, AVG(age) AS 平均年龄
    FROM student
    GROUP BY department;
  3. 建立视图view_grade,内容为学生姓名、课程名、成绩

    1
    2
    3
    4
    5
    6
    7
    CREATE 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
    7
    CREATE 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;
  4. 查询其他系中比信息系某一学生年龄大的学生姓名和年龄

    1
    2
    3
    4
    5
    6
    7
    8
    SELECT 姓名, 年龄
    FROM 学生表
    WHERE 系别 != '信息系'
    AND 年龄 > ANY (
    SELECT 年龄
    FROM 学生表
    WHERE 系别 = '信息系'
    );
  5. 查询其他系中比信息系所有学生年龄大的学生姓名和年龄

    1
    2
    3
    4
    5
    6
    7
    8
    SELECT 姓名, 年龄
    FROM 学生表
    WHERE 系别 != '信息系'
    AND 年龄 > ALL (
    SELECT 年龄
    FROM 学生表
    WHERE 系别 = '信息系'
    );
  6. 分别对学生表、成绩表进行:内连接、左外连接、右外连接、全连接

    • 内连接:
      1
      2
      3
      SELECT *
      FROM 学生表
      INNER JOIN 成绩表 ON 学生表.学号 = 成绩表.学号;
    • 左外连接:
      1
      2
      3
      SELECT *
      FROM 学生表
      LEFT JOIN 成绩表 ON 学生表.学号 = 成绩表.学号;
    • 右外连接:
      1
      2
      3
      SELECT *
      FROM 学生表
      RIGHT JOIN 成绩表 ON 学生表.学号 = 成绩表.学号;
    • 全连接:
      1
      2
      3
      SELECT *
      FROM 学生表
      FULL OUTER JOIN 成绩表 ON 学生表.学号 = 成绩表.学号;

★★★★ 难度4:高级子查询、窗口函数与复杂逻辑

  1. 查询选修了全部课程的学生姓名

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    SELECT 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
    8
    SELECT 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
    11
    SELECT Sname
    FROM S
    WHERE Sno IN (
    SELECT Sno
    FROM SC
    GROUP BY Sno
    HAVING COUNT(DISTINCT Cno) = (
    SELECT COUNT(*)
    FROM C
    )
    );
  2. 查询每门课的间接先修课,要求显示课程名及该课程间接先修课的课程名

    1
    2
    3
    4
    5
    SELECT a.课程名, c.课程名 AS 间接先修课名
    FROM 课程表 a
    LEFT JOIN 课程表 b ON a.先修课号 = b.课程号
    LEFT JOIN 课程表 c ON b.先修课号 = c.课程号
    WHERE c.课程名 IS NOT NULL;
  3. 查询被所有学生选修的课程名

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    SELECT 课程名
    FROM 课程表
    WHERE 课程号 IN (
    SELECT 课程号
    FROM 成绩表
    GROUP BY 课程号
    HAVING COUNT(DISTINCT 学号) = (
    SELECT COUNT(*)
    FROM 学生表
    )
    );
  4. 查询学生成绩5-7名的学生学号、课程号、成绩

    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT 学号, 课程号, 成绩
    FROM (
    SELECT 学号,
    课程号,
    成绩,
    ROW_NUMBER() OVER (ORDER BY 成绩 DESC) AS rn
    FROM 成绩表
    ) t
    WHERE rn BETWEEN 5 AND 7;
  5. 找出每个学生低于他选修课程平均成绩的课程号

    1
    2
    3
    4
    5
    6
    7
    SELECT 学号, 课程号
    FROM 成绩表 a
    WHERE 成绩 < (
    SELECT AVG(成绩)
    FROM 成绩表 b
    WHERE b.学号 = a.学号
    );

★★★★★ 难度5:关系除法(极值子查询)

  1. 查询选修了学生95002选修的全部课程的学生学号
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    SELECT 学号
    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