MYSQL中的联合查询操作(如果想知道MYSQL中有关联合查询操作的知识,那么只看这一篇就足够了!)

发布于:2024-12-18 ⋅ 阅读:(99) ⋅ 点赞:(0)

        前言:在数据库设计中,数据通常分散存储在多个表中,而联合查询通过连接多张表来实现复杂的数据提取和分析需求。它不仅是关联表数据的核心工具,还能高效解决多表协作的问题,是数据库开发中不可或缺的重要技能。


✨✨✨这里是秋刀鱼不做梦的BLOG

✨✨✨想要了解更多内容可以访问我的主页秋刀鱼不做梦-CSDN博客

在正式开始讲解之前,先让我们看一下本文大致的讲解内容:

目录

1.为什么使用联合查询

2.内连接

2.外连接

3.  自连接

4.子查询

子查询的类型:

        【1】标量子查询

        【2】列子查询

        【3】行子查询

        【4】表子查询

5.合并查询


1.为什么使用联合查询

        在开始学习联合查询之前,先让我们了解一下为什么要使用联合查询,在数据库设计中,为了满足范式的要求,数据通常被拆分存储在多个表中,这样的设计能够提高数据的规范性和可维护性,但也带来了数据分散的问题。

        比如说有这样一个例子,当需要查询学生的基本信息和班级信息时,这些数据分别存储在 student 表和 class 表中,需要从多个表中提取数据才能获取完整信息。

        而联合查询正是为了解决这一问题而存在的,通过将多个表关联起来,联合查询可以将分散存储的数据整合到一个结果集中。

        ——所以根据上边我们所讲,联合查询的出现本质上就是为了一个目的——整合多个表的内容。        

        这样我们也就对为什么要使用联合查询有了初步的理解了,那么接下来就让我们学习一下有哪些联合查询的操作吧!

2.内连接

        首先先让我们学习一下内连接。

内连接的基本概念:

内连接返回两个表中满足连接条件的所有记录,通常用于关联主表与外键表的数据。

内连接的基本语法:

SELECT 字段名
FROM 表1 [INNER] JOIN 表2
ON 表1.字段名 = 表2.字段名
WHERE 其他条件;

        了解完了内连接的基本语法之后,让我们使用一个案例来进一步对内连接进行理解:

场景:获取学生及其班级信息
        在学校管理系统中,学生的基本信息和班级信息存储在不同的表中,通过内连接,我们可以查询学生的详细信息及其所属班级名称。

SELECT  -- 选择查询的字段
    s.name AS 学生姓名,  -- 学生表中的姓名字段,别名为 "学生姓名"
    s.sno AS 学号,  -- 学生表中的学号字段,别名为 "学号"
    c.name AS 班级名称  -- 班级表中的名称字段,别名为 "班级名称"
FROM 
    student s  -- 从学生表(s)查询数据
INNER JOIN 
    class c  -- 使用 INNER JOIN 连接班级表(c)
ON 
    s.class_id = c.id;  -- 学生表的 class_id 与 班级表的 id 匹配

解释:

  • s.class_id = c.id 指定连接条件,确保学生与其班级正确匹配。
  • 查询结果包括学生姓名、学号及班级名称,便于管理者快速查看学生的基本信息。

        这样我们就对内连接有了一定的了解了!

2.外连接

        在了解完了内连接之后,在让我们看一下外连接。

外连接的基本概念:

外连接分为左外连接、右外连接,用于返回一张表的所有记录,以及另一张表中与之匹配的数据(如果有的话)。

外连接的基本语法:

-- 左外连接
SELECT 字段名
FROM 表1 LEFT JOIN 表2
ON 表1.字段名 = 表2.字段名;

-- 右外连接
SELECT 字段名
FROM 表1 RIGHT JOIN 表2
ON 表1.字段名 = 表2.字段名;

        当然,光看上述的代码可能有点晦涩难懂,那么接下来让我们使用两个案例来讲解一下:

案例1:查询所有学生及其考试成绩
        在成绩管理系统中,需要获取所有学生的成绩信息,包括未参加考试的学生。

SELECT  -- 选择查询的字段
    s.name AS 学生姓名,  -- 学生表中的姓名字段,别名为 "学生姓名"
    sc.score AS 成绩  -- 成绩表中的分数字段,别名为 "成绩"
FROM 
    student s  -- 从学生表(s)查询数据
LEFT JOIN 
    score sc  -- 使用 LEFT JOIN 连接成绩表(sc)
ON 
    s.id = sc.student_id;  -- 学生表的 id 与 成绩表的 student_id 匹配

解释:

  • LEFT JOIN 确保学生表中的所有记录都出现在结果中,即使成绩表中没有匹配的记录。
  • 未匹配的成绩字段将显示为 NULL,表明该学生未参加考试。

案例2:查询未被分配学生的班级
        当某些班级尚未分配学生时,使用右外连接可快速定位这些班级。

SELECT  -- 选择查询的字段
    c.name AS 班级名称  -- 班级表中的名称字段,别名为 "班级名称"
FROM 
    student s  -- 学生表(s)
RIGHT JOIN 
    class c  -- 使用 RIGHT JOIN 连接班级表(c)
ON 
    s.class_id = c.id  -- 学生表的 class_id 与 班级表的 id 匹配
WHERE 
    s.id IS NULL;  -- 筛选没有学生的班级

解释:

  • RIGHT JOIN 以班级表为基准,确保所有班级信息都显示在结果中。
  • s.id IS NULL 用于过滤没有学生分配的班级。

        至此,我们就了解了Mysql中的外连接了!

3.  自连接

        接下来让我们看一下自连接。

自连接的基本概念:

自连接是对同一张表进行连接操作,通过为同一张表设置不同的别名,自连接可以将表看作两张表进行连接,用于行间数据的比较和关联。

自连接的基本语法:

SELECT 字段列表  
FROM 表名 别名1, 表名 别名2  
WHERE 别名1.字段名 = 别名2.字段名  
  AND 其他条件;

对于自连接,有两个注意事项:

  1. 表别名:
    自连接必须为表设置别名,便于区分同一表的不同引用。

  2. 连接条件:
    使用 WHERE 子句指定连接条件,例如两个字段相等或满足其他关系。

        了解完了自连接的基本语法之后,让我们使用一个案例来进一步对自连接进行理解:

案例:比较相同学生的两门课程成绩

        要求查询出“MySQL”成绩高于“Java”成绩的学生信息。

SELECT  -- 选择查询的字段
    s1.student_id AS 学生ID,  -- 从 score 表 s1 中选取 student_id 字段,别名为 "学生ID"
    s1.score AS MySQL成绩,  -- 从 score 表 s1 中选取 score 字段,别名为 "MySQL成绩"
    s2.score AS Java成绩  -- 从 score 表 s2 中选取 score 字段,别名为 "Java成绩"
FROM 
    score s1, score s2  -- 从同一个 score 表(使用别名 s1 和 s2)查询
WHERE 
    s1.student_id = s2.student_id  -- 连接条件:选取同一学生的记录
    AND s1.course_id = 3          -- MySQL 课程的课程ID为 3
    AND s2.course_id = 1          -- Java 课程的课程ID为 1
    AND s1.score > s2.score;      -- 筛选条件:MySQL 成绩高于 Java 成绩

解释:

  • s1s2score 表的两个别名,分别表示 MySQL 和 Java 课程的成绩记录。
  • s1.student_id = s2.student_id 确保比较的是同一个学生的成绩。
  • 其他条件过滤出符合需求的记录(如课程 ID 和成绩差异)。

4.子查询

        学习完自连接之后,在让我们学习一下子查询,首先先让我们了解一下子查询的基本概念:

子查询是一个嵌套在主查询(外部查询)中的查询,可以帮助你对复杂查询进行分解,获取主查询所需的数据,子查询的执行通常在主查询之前完成,并且其结果可以被用作主查询的一部分。

当然子查询一般出现在一下的位置:

  • WHERE 子句:在WHERE条件中使用子查询,通常用于筛选符合某条件的记录。
  • FROM 子句:子查询作为一个虚拟表使用,提供给主查询的数据源。
  • SELECT 子句:子查询可以作为一个列,用来返回特定的值。
  • INSERT、UPDATE、DELETE 子句:子查询可以用来提供插入、更新或删除操作的数据。

        通过上述的讲解,我们就对子查询有了一定的了解了,那么接下来就让我们学习一下子查询的类型,并通过这些类型中的例子,来进一步理解如何去使用子查询。

子查询的类型:

        【1】标量子查询

        ——标量子查询返回单一的单个值,通常用于SELECTWHERE子句中。

例子:

SELECT name  -- 选择查询员工姓名
FROM employees  -- 从 employees 表中查询数据
WHERE salary > (  -- 筛选条件:工资大于子查询结果
    SELECT AVG(salary)  -- 子查询:计算所有员工的平均工资
    FROM employees  -- 从 employees 表中计算平均工资
);

        在这个例子中,子查询 (SELECT AVG(salary) FROM employees) 计算了所有员工的平均工资,主查询返回那些工资高于平均工资的员工。

        【2】列子查询

        ——列子查询返回单列的多个值,通常用于INNOT IN等操作符。

例子:

SELECT name  -- 选择查询员工姓名
FROM employees  -- 从 employees 表中查询数据
WHERE department_id IN (  -- 筛选条件:员工的部门ID在子查询结果中
    SELECT department_id  -- 子查询:选择符合条件的部门ID
    FROM departments  -- 从 departments 表中查询数据
    WHERE location = 'New York'  -- 筛选部门所在地为 'New York' 的部门
);

        这里,子查询返回所有位于“New York”位置的部门ID,主查询返回属于这些部门的员工。

        【3】行子查询

        ——行子查询返回单行多列的多个值,通常用于= (subquery)的方式进行比较。

例子:

SELECT name, salary  -- 选择查询员工姓名和工资
FROM employees  -- 从 employees 表中查询数据
WHERE (department_id, salary) = (  -- 筛选条件:部门ID和工资匹配子查询的结果
    SELECT department_id, MAX(salary)  -- 子查询:每个部门的最高工资
    FROM employees  -- 从 employees 表查询数据
    GROUP BY department_id  -- 按部门分组,计算每个部门的最高工资
);

        这个例子中,子查询 (SELECT department_id, MAX(salary) FROM employees GROUP BY department_id) 返回每个部门的最大工资和部门ID,主查询用于查找这些工资最高的员工。

        【4】表子查询

        ——表子查询返回多行多列数据,通常用在FROM子句中,作为虚拟表来参与联接操作。

例子:

SELECT e.name, e.salary  -- 选择查询员工姓名和工资
FROM employees e  -- 从 employees 表中查询数据,并给表起别名 e
JOIN (  -- 将主查询与子查询连接
    SELECT department_id, MAX(salary) AS max_salary  -- 子查询:按部门分组并获取每个部门的最高工资,命名为 max_salary
    FROM employees  -- 从 employees 表中查询数据
    GROUP BY department_id  -- 按部门ID分组
) AS dept_max_salary  -- 给子查询结果取别名 dept_max_salary
ON e.department_id = dept_max_salary.department_id  -- 将员工表和子查询结果按部门ID连接
WHERE e.salary = dept_max_salary.max_salary;  -- 筛选员工工资等于该部门的最高工资

        在这个查询中,子查询 (SELECT department_id, MAX(salary) FROM employees GROUP BY department_id) 生成了一个包含部门ID和最大工资的临时表,并与employees表联接,返回每个部门工资最高的员工。

        至此我们就大致的了解了有关子查询的类型了!希望读者可以根据上述的案例对子查询有自己的理解!

5.合并查询

        最后在让我们学习一下合并查询,合并查询允许你将两个或多个查询的结果合并成一个结果集,每个查询的结果必须有相同数量的列,并且列的数据类型应该兼容。UNION 主要有两种形式:

  • UNION:默认情况下,UNION 会去除重复的结果。
  • UNION ALLUNION ALL 不会去重,会返回所有的结果,包括重复的行。

了解完了合并查询的基本概念之后,在让我们学习一下合并查询的语法:

SELECT column1, column2 FROM table1
UNION
SELECT column1, column2 FROM table2;

        这样我们就大致的了解了什么是联合查询了,那么接下来让我们使用一个案例来讲解一下合并查询该如何去使用:

例子:

假设有两个表:employees_2019employees_2020,你想查询这两年中所有员工的姓名和职位:

SELECT name, position  -- 选择查询员工姓名和职位
FROM employees_2019  -- 从 2019 年的员工表中获取数据
UNION  -- 合并两个查询的结果,并去重
SELECT name, position  -- 选择查询员工姓名和职位
FROM employees_2020;  -- 从 2020 年的员工表中获取数据

        这段 SQL 查询使用了 UNION,将两个表 (employees_2019employees_2020) 中的员工姓名和职位合并成一个结果集。

        ——当然如果你希望保留重复的员工记录,可以使用 UNION ALL

SELECT name, position  -- 选择查询员工姓名和职位
FROM employees_2019  -- 从 2019 年的员工表中获取数据
UNION ALL  -- 合并两个查询的结果,不去重
SELECT name, position  -- 选择查询员工姓名和职位
FROM employees_2020;  -- 从 2020 年的员工表中获取数据

        这段 SQL 查询使用了 UNION ALL,将两个表 (employees_2019employees_2020) 中的员工姓名和职位合并成一个结果集,只不过与 UNION 不同,UNION ALL 不会去重,所以重复的员工记录会保留。

        这样我们就了解了联合查询的全部内容了!


以上就是本篇文章全部内容~~


网站公告

今日签到

点亮在社区的每一天
去签到