当前位置: 首页 > article >正文

【数据库】SQL语言:SELECT语句的练习(例题)

复试面试准备数据库,本文为知识点例题讲解,例题来源课上笔记


1. 定义与基础

1.1基本语法

  • SELECT: 指定要查询的列。
  • FROM: 指定要查询的表。
  • WHERE: 可选,用于过滤记录。

SELECT 语句用于从表中查询数据,其基础格式如下:

SELECT 列名 FROM 表名 WHERE 条件 ORDER BY 排序顺序;

    2. 基础查询

    2.1 查询所有数据

    SELECT * FROM 学生;

    假设 学生 表数据如下:

    学号姓名专业
    1张三软件
    2李四网络
    3王五软件

    2.2 查询指定字段

    SELECT 学号, 姓名
    FROM 学生
    WHERE 专业 = '软件';
    

    必修课 表数据如下:

    课号课程名
    101数据库
    102数据结构
    101数据库

    列出软件专业全部学生的学号及姓名

    学号姓名
    1张三
    3王五

    2.3 去重查询

    SELECT DISTINCT 课号
    FROM 必修课;

    列出所有必修课的课号

    课号
    101
    102

    3. 筛选数据 (WHERE)

    3.1 基础条件查询

    SELECT * FROM students WHERE age > 18;
    

    3.2 多条件查询

    1. 求 1 号课成绩⼤于 80 分的学⽣的学号及成绩,并按成绩由⾼到低列出。
    SELECT 学号, 成绩
    FROM 选课
    WHERE 课号 = '1' AND 成绩 > 80
    ORDER BY 成绩 DESC;

    假设 选课 表数据如下:

    学号课号成绩
    1185
    2175
    3190
    4288
    5195

    查询结果

    执行上述查询后,结果将是:

    学号成绩
    595
    390
    185

    2.列出非软件专业学生的名单。

    方法一:使用 <> 运算符
    SELECT 姓名
    FROM 学生
    WHERE 专业 <> "软件";
    方法二:使用 NOT 运算符
    SELECT 姓名
    FROM 学生
    WHERE NOT 专业 = "软件";
    方法三:使用 != 运算符
    SELECT 姓名
    FROM 学生
    WHERE 专业 != "软件";

    示例数据

    假设 学生 表数据如下:

    学号姓名专业
    1张三软件
    2李四网络
    3王五软件
    4赵六电子

    查询结果

    无论使用哪种方法,查询结果都将是:

    姓名
    李四
    赵六
    1. 列出选修1号课或3号课的全体学生的学号和成绩

    方法一:使用 OR 运算符

    SELECT 学号, 成绩
    FROM 选课
    WHERE 课号 = "1" OR 课号 = "3";

    方法二:使用 IN 运算符

    SELECT 学号, 成绩
    FROM 选课
    WHERE 课号 IN ("1", "3");
    2. 列出没有选修1号课和3号课的学生的学号和成绩

    方法一:使用 != 和 AND 运算符

    SELECT 学号, 成绩
    FROM 选课
    WHERE 课号 != "1" AND 课号 != "3";

    方法二:使用 NOT IN 运算符

    SELECT 学号, 成绩
    FROM 选课
    WHERE 课号 NOT IN ("1", "3");

    示例数据

    假设 选课 表数据如下:

    学号课号成绩
    1185
    2275
    3190
    4388
    5295

    查询结果
    1. 列出选修1号课或3号课的全体学生的学号和成绩

    无论使用哪种方法,查询结果都将是:

    学号成绩
    185
    390
    488
    2. 列出没有选修1号课和3号课的学生的学号和成绩

    无论使用哪种方法,查询结果都将是:

    学号成绩
    275
    595

    3.3 模糊查询

    . 列出所有98级学生的学生成绩情况

    方法一:使用 LIKE "98%"

    SELECT *
    FROM 选课
    WHERE 学号 LIKE "98%";

    方法二:使用 LIKE "98_"

    SELECT *
    FROM 选课
    WHERE 学号 LIKE "98_";
    2. 列出非98级学生的学生成绩情况

    方法一:使用 NOT LIKE "98%"

    SELECT *
    FROM 选课
    WHERE 学号 NOT LIKE "98%";

    方法二:使用 NOT LIKE "98_"

    SELECT *
    FROM 选课
    WHERE 学号 NOT LIKE "98_";

    示例数据

    假设 选课 表数据如下:

    学号课号成绩
    98001185
    98002175
    99001190
    98003288
    99002295

    查询结果
    1. 列出所有98级学生的学生成绩情况
    • 方法一​(LIKE "98%"):

      学号课号成绩
      98001185
      98002175
      98003288
    • 方法二​(LIKE "98_"):

      学号课号成绩
      98001185
      98002175
      98003288
    2. 列出非98级学生的学生成绩情况
    • 方法一​(NOT LIKE "98%"):

      学号课号成绩
      99001190
      99002295
    • 方法二​(NOT LIKE "98_"):

      学号课号成绩
      99001190
      99002295

    3.4 范围查询

    1. 查询成绩在70到80分之间的选课记录

    方法一:使用 >= 和 <= 运算符

    SELECT *
    FROM 选课
    WHERE 成绩 >= 70 AND 成绩 <= 80;

    方法二:使用 BETWEEN 运算符

    SELECT *
    FROM 选课
    WHERE 成绩 BETWEEN 70 AND 80;
    2. 查询不在70到80分范围内的选课记录

    方法一:使用 <= 和 >= 运算符

    SELECT *
    FROM 选课
    WHERE 成绩 <= 70 OR 成绩 >= 80;

    方法二:使用 NOT BETWEEN 运算符

    SELECT *
    FROM 选课
    WHERE 成绩 NOT BETWEEN 70 AND 80;

    示例数据

    假设 选课 表数据如下:

    学号课号成绩
    1165
    2175
    3185
    4270
    5280

    查询结果
    1. 查询成绩在70到80分之间的选课记录

    无论使用哪种方法,查询结果都将是:

    学号课号成绩
    2175
    4270
    5280
    2. 查询不在70到80分范围内的选课记录

    无论使用哪种方法,查询结果都将是:

    学号课号成绩
    1165
    3185

    4. 排序数据 (ORDER BY)

    4.1 按成绩降序排列

    SELECT * FROM students ORDER BY score DESC;
    

    4.2 按年龄升序、成绩降序排列

    SELECT * FROM students ORDER BY age ASC, score DESC;
    

    5. 聚合查询 (GROUP BY + HAVING)

    5.1 统计每个年龄段的学生人数

    SELECT age, COUNT(*) AS student_count FROM students GROUP BY age;
    

    5.2 计算不同性别的平均成绩

    SELECT gender, AVG(score) AS avg_score FROM students GROUP BY gender;
    

    5.3 统计学生数量大于2的年龄段

    SELECT age, COUNT(*) AS student_count FROM students GROUP BY age HAVING COUNT(*) > 2;
    

    6. 连接查询 (JOIN)  重要!!

    6.​1 连接查询的基本概念

    • 连接查询:用于从多个表中提取数据,并通过相关列建立表之间的关联。
    • 常用连接类型
      • 内连接(INNER JOIN)​:只返回满足连接条件的记录。
      • 外连接(LEFT JOIN, RIGHT JOIN, FULL JOIN)​:返回满足连接条件的记录以及不满足条件的部分记录。
      • 自连接(SELF JOIN)​:将表与自身连接。
    • 连接条件:通过 ON 或 WHERE 子句指定表之间的关联列。

    ​6.2 内连接查询

    知识点讲解
    • INNER JOIN:默认的连接类型,返回满足连接条件的记录。
    • 语法
      SELECT 列1, 列2, ...
      FROM 表1
      INNER JOIN 表2 ON 表1.列 = 表2.列;
    • 等价写法:在 WHERE 子句中指定连接条件(旧式写法)。
    SQL 代码示例
    1. 列出选修1号课的学生姓名及成绩

      SELECT 姓名, 成绩
      FROM 学生, 选课
      WHERE 学生.学号 = 选课.学号 AND 课号 = '1';

      等价写法

      SELECT 姓名, 成绩
      FROM 学生
      INNER JOIN 选课 ON 学生.学号 = 选课.学号
      WHERE 课号 = '1';
    2. 列出选修1号课的学生的学号、姓名及成绩

      SELECT 学生.学号, 姓名, 成绩
      FROM 学生, 选课
      WHERE 学生.学号 = 选课.学号 AND 课号 = '1';

      等价写法

      SELECT 学生.学号, 姓名, 成绩
      FROM 学生
      INNER JOIN 选课 ON 学生.学号 = 选课.学号
      WHERE 课号 = '1';

    3. 分组聚合查询

    知识点讲解
    • GROUP BY:用于对结果集进行分组,通常与聚合函数(如 SUMCOUNTAVG 等)一起使用。
    • HAVING:用于过滤分组后的结果集。
    • SUM 函数:计算指定列的总和。
    SQL 代码示例
    • 求出总分大于150的学生的学号、姓名及总成绩
      SELECT 学生.学号, 姓名, SUM(成绩) AS 总成绩
      FROM 学生, 选课
      WHERE 学生.学号 = 选课.学号
      GROUP BY 选课.学号
      HAVING SUM(成绩) > 150;
      等价写法
      SELECT 学生.学号, 姓名, SUM(成绩) AS 总成绩
      FROM 学生
      INNER JOIN 选课 ON 学生.学号 = 选课.学号
      GROUP BY 选课.学号
      HAVING SUM(成绩) > 150;

    为什么这里要用到GROUP BY?

    1. GROUP BY 的作用:

      • 将结果集按指定的列(或多个列)进行分组。
      • 在本例中,按 选课.学号 分组,即对每个学生的选课记录进行分组。
    2. SUM(成绩) 的作用:

      • 对每个分组中的 成绩 列进行求和。
      • 如果没有 GROUP BYSUM(成绩) 会计算整个表的 成绩 总和,而不是每个学生的总成绩。
    3. HAVING 的作用:

      • 用于过滤分组后的结果集。
      • 在本例中,筛选出总成绩大于 150 的学生。
    4. 为什么需要 GROUP BY

      • 如果不使用 GROUP BY,查询会报错,因为 SUM(成绩) 是一个聚合函数,而 学生.学号 和 姓名 是非聚合列,SQL 无法确定如何将这两者关联。
      • GROUP BY 明确指定了按 选课.学号 分组,从而可以正确计算每个学生的总成绩。

    示例数据

    假设 学生 表数据如下:

    学号姓名
    1张三
    2李四
    3王五

    选课 表数据如下:

    学号课号成绩
    1180
    1290
    2170
    2260
    3185
    3295

    查询结果

    执行上述查询后,结果将是:

    学号姓名总成绩
    1张三170
    3王五180

     

    1. 学号 = 1
      • 成绩:80 + 90 = 170。
      • 总成绩大于 150,符合条件。
    2. 学号 = 2
      • 成绩:70 + 60 = 130。
      • 总成绩不大于 150,不符合条件。
    3. 学号 = 3
      • 成绩:85 + 95 = 180。
      • 总成绩大于 150,符合条件。


    4. 连接查询的注意事项

    1. 明确连接条件:连接查询必须指定表之间的关联列,否则会产生笛卡尔积(Cartesian Product),导致结果集过大。
    2. 使用表别名:当表名较长或查询涉及多个表时,可以使用表别名简化代码。
      SELECT s.学号, s.姓名, c.成绩
      FROM 学生 AS s
      INNER JOIN 选课 AS c ON s.学号 = c.学号
      WHERE c.课号 = '1';
    3. 避免歧义列名:如果多个表中有相同的列名,必须使用表名或别名限定列名,例如 学生.学号

    5. 连接查询的综合应用

    示例:查询每个学生的总成绩及平均成绩
    SELECT 学生.学号, 姓名, SUM(成绩) AS 总成绩, AVG(成绩) AS 平均成绩
    FROM 学生
    INNER JOIN 选课 ON 学生.学号 = 选课.学号
    GROUP BY 学生.学号, 姓名;
    示例:查询选修了1号课和2号课的学生
    SELECT 学生.学号, 姓名
    FROM 学生
    INNER JOIN 选课 AS c1 ON 学生.学号 = c1.学号 AND c1.课号 = '1'
    INNER JOIN 选课 AS c2 ON 学生.学号 = c2.学号 AND c2.课号 = '2';

    假设还有一个 courses 表,包括 course_id (课程ID) 和 student_id (学生ID)

    6.3 自连接 (SELF JOIN)

    1. 列出专业相同的学生姓名及专业信息

    SELECT a.姓名, b.姓名, 专业
    FROM 学生 a, 学生 b
    WHERE a.学号 <> b.学号 AND a.专业 = b.专业;
    知识点讲解
    1. 自连接(SELF JOIN)​

      • 将 学生 表与自身连接,生成两个实例 a 和 b
      • 通过 a.学号 <> b.学号 确保排除同一个学生。
      • 通过 a.专业 = b.专业 筛选出专业相同的学生。
    2. 查询逻辑

      • 从 学生 表中选取两个实例 a 和 b
      • 筛选出学号不同但专业相同的学生。
      • 返回这些学生的姓名及专业信息。
    示例数据

    假设 学生 表数据如下:

    学号姓名专业
    1张三软件
    2李四网络
    3王五软件
    4赵六电子
    查询结果
    姓名姓名专业
    张三王五软件
    王五张三软件

    2. 求至少选修1号课和2号课的学生的学号

    SQL 查询语句
    SELECT X.学号
    FROM 选课 X, 选课 Y
    WHERE X.学号 = Y.学号 AND X.课号 = "1" AND Y.课号 = "2";
    知识点讲解
    1. 自连接(SELF JOIN)​

      • 将 选课 表与自身连接,生成两个实例 X 和 Y
      • 通过 X.学号 = Y.学号 确保是同一个学生。
      • 通过 X.课号 = "1" 和 Y.课号 = "2" 筛选出同时选修1号课和2号课的学生。
    2. 查询逻辑

      • 从 选课 表中选取两个实例 X 和 Y
      • 筛选出同一个学生(X.学号 = Y.学号),且选修了1号课(X.课号 = "1")和2号课(Y.课号 = "2")。
      • 返回这些学生的学号。
    示例数据

    假设 选课 表数据如下:

    学号课号成绩
    1185
    2175
    3190
    1288
    3295
    4280
    查询结果
    学号
    1
    3

    6.2 左连接 (LEFT JOIN)

    SELECT students.name, courses.course_name
    FROM students
    LEFT JOIN courses ON students.id = courses.student_id;
    

    7.嵌套查询

    7.1. 嵌套查询的基本概念

    • 嵌套查询:在一个查询中嵌套另一个查询,通常用于解决复杂的查询需求。
    • 子查询:嵌套在查询中的查询,可以出现在 SELECTFROMWHERE 或 HAVING 子句中。
    • 常用运算符
      • IN:用于匹配子查询的结果。
      • EXISTS:用于检查子查询是否返回结果。
      • ANY/ALL:用于比较子查询的结果。

    ​7.2 嵌套查询的示例

    示例 1:列出选修汇编语言课的学生的学号

    方法一:使用 IN 子查询

    SELECT 学号
    FROM 选课
    WHERE 课号 IN (SELECT 课号 FROM 课程 WHERE 课名 = "汇编语言");

    方法二:使用 EXISTS 子查询

    SELECT 学号
    FROM 选课
    WHERE EXISTS (SELECT * FROM 课程 WHERE 课名 = "汇编语言" AND 选课.课号 = 课程.课号);
    • IN 子查询:
      • 子查询返回一个值列表,主查询筛选出匹配这些值的记录。
      • 适用于子查询返回结果较少的情况。
    • EXISTS 子查询:
      • 子查询返回一个布尔值(TRUE 或 FALSE),主查询根据布尔值筛选记录。
      • 适用于子查询返回结果较多或需要关联主查询的情况。

    示例 2:求软件专业所有必修课的课程信息

    方法一:使用 IN 子查询

    SELECT *
    FROM 课程
    WHERE 课号 IN (SELECT 课号 FROM 必修课 WHERE 必修专业 = "软件");

    方法二:使用 EXISTS 子查询

    SELECT *
    FROM 课程
    WHERE EXISTS (SELECT * FROM 必修课 WHERE 必修专业 = "软件" AND 课程.课号 = 必修课.课号);

    示例3:求选修2号课的学生中,成绩比选修1号课的最低成绩要高的学生的学号和成绩

    方法一:使用子查询

    SELECT 学号, 成绩
    FROM 选课
    WHERE 课号 = "2" AND 成绩 > (
        SELECT MIN(成绩)
        FROM 选课
        WHERE 课号 = "1"
    );

    解题思路

    1. 子查询:获取选修1号课的最低成绩。
      SELECT MIN(成绩) FROM 选课 WHERE 课号 = "1";
    2. 主查询:筛选出选修2号课且成绩高于子查询结果的学生。
      SELECT 学号, 成绩 FROM 选课 WHERE 课号 = "2" AND 成绩 > (子查询结果);
    方法二:使用 ANY 关键字
    SELECT 学号, 成绩
    FROM 选课
    WHERE 课号 = "2" AND 成绩 > ANY (
        SELECT 成绩
        FROM 选课
        WHERE 课号 = "1"
    );

    解题思路

    1. 子查询:获取选修1号课的所有成绩。
      SELECT 成绩 FROM 选课 WHERE 课号 = "1";
    2. 主查询:筛选出选修2号课且成绩高于子查询中任意一个成绩的学生。
      SELECT 学号, 成绩 FROM 选课 WHERE 课号 = "2" AND 成绩 > ANY (子查询结果);

    示例4:求选修2号课的学生中,成绩比选修1号课的任何学生的成绩都要高的那些学生的学号和成绩
    方法一:使用子查询
    SELECT 学号, 成绩
    FROM 选课
    WHERE 课号 = "2" AND 成绩 > (
        SELECT MAX(成绩)
        FROM 选课
        WHERE 课号 = "1"
    );

    解题思路

    1. 子查询:获取选修1号课的最高成绩。
      SELECT MAX(成绩) FROM 选课 WHERE 课号 = "1";
    2. 主查询:筛选出选修2号课且成绩高于子查询结果的学生。
      SELECT 学号, 成绩 FROM 选课 WHERE 课号 = "2" AND 成绩 > (子查询结果);
    方法二:使用 ALL 关键字
    SELECT 学号, 成绩
    FROM 选课
    WHERE 课号 = "2" AND 成绩 > ALL (
        SELECT 成绩
        FROM 选课
        WHERE 课号 = "1"
    );

    解题思路

    1. 子查询:获取选修1号课的所有成绩。
      SELECT 成绩 FROM 选课 WHERE 课号 = "1";
    2. 主查询:筛选出选修2号课且成绩高于子查询中所有成绩的学生。
      SELECT 学号, 成绩 FROM 选课 WHERE 课号 = "2" AND 成绩 > ALL (子查询结果);

    示例5列出每门课程中成绩最高的选课信息
    SELECT *
    FROM 选课 A
    WHERE 成绩 = (
        SELECT MAX(成绩)
        FROM 选课 B
        WHERE A.课号 = B.课号
    );
    知识点讲解
    1. 嵌套查询
      • 在主查询中嵌套了一个子查询。
      • 子查询的作用是找到每门课程的最高成绩。
    2. 子查询逻辑
      • SELECT MAX(成绩) FROM 选课 B WHERE A.课号 = B.课号
        • 从 选课 表(别名 B)中找到与主查询当前记录(A.课号)相同的课程的最高成绩。
    3. 主查询逻辑
      • 从 选课 表(别名 A)中筛选出成绩等于子查询结果的记录,即每门课程中成绩最高的选课信息。

    示例6: 列出每个学生中成绩低于本人平均成绩的选课信息
    SELECT *
    FROM 选课 A
    WHERE 成绩 < (
        SELECT AVG(成绩)
        FROM 选课 B
        WHERE A.学号 = B.学号
    );
    知识点讲解
    1. 嵌套查询
      • 在主查询中嵌套了一个子查询。
      • 子查询的作用是计算每个学生的平均成绩。
    2. 子查询逻辑
      • SELECT AVG(成绩) FROM 选课 B WHERE A.学号 = B.学号
        • 从 选课 表(别名 B)中找到与主查询当前记录(A.学号)相同的学生的平均成绩。
    3. 主查询逻辑
      • 从 选课 表(别名 A)中筛选出成绩低于子查询结果的记录,即每个学生中成绩低于本人平均成绩的选课信息。

    7.​3. 嵌套查询的注意事项

    1. 子查询的结果

      • 子查询必须返回一个值或一组值,以便主查询使用。
      • 例如:IN 子查询必须返回一个值列表,EXISTS 子查询必须返回一个布尔值。
    2. 子查询的性能

      • 子查询可能会影响查询性能,尤其是在数据量较大时。
      • 优化子查询的方法包括:
        • 使用索引。
        • 将子查询改写为连接查询。
    3. 子查询的嵌套深度

      • 子查询可以嵌套多层,但嵌套深度过深会增加查询复杂度,降低可读性。

    总结

    SELECT 语句是 SQL 语言中最重要的查询工具,通过 WHERE 条件筛选,ORDER BY 排序,GROUP BY 聚合,JOIN 连接以及子查询等方式,可以高效地查询和分析数据。通过本文系统地练习,可以打定深厚的 SQL 学习基础。

    综合练习主页接


    http://www.kler.cn/a/610393.html

    相关文章:

  • Hadoop/Spark 生态
  • websocket结合promise的通信协议
  • LinkedIn数据抓取零风险指南:亮数据住宅代理实现企业级合规采集
  • 医学交互作用分析步骤和目的(R语言)
  • 我的世界1.20.1forge模组进阶开发教程——结构(3)
  • Pytorch学习笔记(七)Learn the Basics - Optimizing Model Parameters
  • Redis 存储 String高亮显示JSON,存储 JSON 的标准工具方法
  • 华为OD机试A卷 - 积木最远距离(C++ Java JavaScript Python )
  • 【前端扫盲】node.js npm nvm都是什么以及他们之间的关系
  • 海底高铁--差分
  • react组件中useRef声明的变量和let声明的变量区别
  • 清华大学第十二版!!《机器语言大模型赋能软件自主可控与安全可信》
  • linux的基础命令
  • redis 缓存穿透
  • Spring Boot网站性能优化全解析
  • 浏览器渲染原理与优化详解
  • 【redis】哨兵节点作用演示和重选主节点详细流程
  • 简单方法胜过大语言模型?!单细胞扰动敲除方法的实验
  • Rust从入门到精通之入门篇:5.控制流
  • AOA与TOA混合定位,MATLAB例程,自适应基站数量,三维空间下的运动轨迹,滤波使用EKF