左连接、右连接、自连接、内连接、全连接、NUION操作符

字段连接,行变换。

左连接与右连接

在MySQL数据库中,左连接(LEFT JOIN)和右连接(RIGHT JOIN)是两种不同类型的连接操作,它们用于将两个或多个表中的数据根据一定的条件结合起来。这两种连接操作的主要区别在于它们保留数据的方式。

  1. 左连接(LEFT JOIN)

    • 左连接会返回左表(即 LEFT JOIN 语句中的第一个表)的所有记录,即使右表中没有匹配的记录。

    • 如果右表中有匹配的记录,那么这些记录会被包含在结果集中。

    • 如果右表中没有匹配的记录,那么结果集中右表的部分会用 NULL 填充。

    示例 SQL 语句:

    SELECT a.*, b.*
    FROM table1 a
    LEFT JOIN table2 b ON a.id = b.id;
  2. 右连接(RIGHT JOIN)

    • 右连接会返回右表(即 RIGHT JOIN 语句中的第二个表)的所有记录,即使左表中没有匹配的记录。

    • 如果左表中有匹配的记录,那么这些记录会被包含在结果集中。

    • 如果左表中没有匹配的记录,那么结果集中左表的部分会用 NULL 填充。

    示例 SQL 语句:

    SELECT a.*, b.*
    FROM table1 a
    RIGHT JOIN table2 b ON a.id = b.id;

在实际应用中,左连接和右连接的使用取决于你希望保留哪个表的记录。通常,左连接用于保留主表(或左表)的所有记录,而右连接用于保留关联表(或右表)的所有记录。

左右连接理解

在MySQL中使用左连接(LEFT JOIN)时,如果右表(被连接的表)中有多个记录与左表(主表)中的一条记录相匹配,那么左连接的结果会为左表中的每一条记录生成多个行,每个行对应右表中的一个匹配记录。这意味着左表中的一条记录可能会在结果集中出现多次,每次出现都与右表中的一个不同的匹配记录相关联。

这种特性有时被称为“笛卡尔积”效果,因为左表的每一行都与右表中所有匹配的行组合。

例如,假设我们有两个表:

  • orders 表(左表)

    • order_id (订单ID)

    • customer_id (客户ID)

  • order_details 表(右表)

    • order_detail_id (订单详情ID)

    • order_id (订单ID)

    • product_name (产品名称)

如果一个订单(orders 表中的一条记录)有多个订单详情(order_details 表中的多条记录),使用左连接查询时,每个订单会与它的所有订单详情一起显示在结果集中。

SQL查询示例:

SELECT o.order_id, o.customer_id, d.product_name
FROM orders o
LEFT JOIN order_details d ON o.order_id = d.order_id;

如果订单ID为1的订单在orders表中有一条记录,而在order_details表中有三条与之匹配的记录,那么在结果集中,订单ID为1的记录将出现三次,每次对应一个不同的产品名称。

结果集可能如下所示:

order_id | customer_id | product_name
------------------------------------
1        | 101         | Product A
1        | 101         | Product B
1        | 101         | Product C

在这个结果集中,订单ID为1的记录出现了三次,每次与不同的产品名称相关联。这就是左连接在右表中有多个匹配记录时的行为。

自连接

自连接(Self Join)是一种特殊的连接操作,它允许一个表与自身进行连接。自连接通常用于查询具有层次(树)或递归关系的数据,例如组织结构、层级关系、递归分类等。

在自连接中,同一个表被当作两个不同的表来使用,通常通过给表取别名来区分。连接条件通常涉及到表中的某个字段与另一个字段的比较。

示例

假设我们有一个名为 employees 的表,它包含员工的信息,包括每个员工的直接上级(manager_id):

CREATE TABLE employees (
    employee_id INT,
    employee_name VARCHAR(100),
    manager_id INT,
    dept_name VARCHAR(100)
);

这个表中,employee_id 是员工的唯一标识,manager_id 是该员工直接上级的 employee_id。我们可以通过自连接来查询每个员工及其直接上级的信息。

SQL 查询

以下是一个自连接的示例查询,用于找出每个员工及其直接上级的名字:

SELECT 
    e1.employee_name AS 'Employee',
    e2.employee_name AS 'Manager'
FROM 
    employees e1
LEFT JOIN 
    employees e2 ON e1.manager_id = e2.employee_id;

在这个查询中:

  • e1employees 表的第一个实例,代表员工。

  • e2employees 表的第二个实例,代表员工的直接上级。

结果解释

假设表中的数据如下:

employee_id | employee_name | manager_id | dept_name
-----------------------------------------------
1           | Alice         | NULL       | HR
2           | Bob           | 1          | IT
3           | Carol         | 1          | IT
4           | Dave          | 2          | IT

查询结果将是:

Employee | Manager
-----------------
Alice    | NULL
Bob       | Alice
Carol     | Alice
Dave      | Bob

在这个结果中,Alice 没有直接上级,因为她的 manager_idNULL。其他员工的直接上级显示在 "Manager" 列中。

用途

自连接在处理具有层级或递归关系的数据时非常有用,例如:

  • 组织结构图

  • 产品分类

  • 递归查询,如找到所有下属或所有上级

自连接是数据库查询中一个强大的工具,可以帮助你理解和操作复杂的数据关系。

内连接、全连接

需要注意的是,MySQL 也支持内连接(INNER JOIN),它只返回两个表中匹配的记录。此外,还有全连接(FULL JOIN),它返回左表和右表中的所有记录,但 MySQL 原生不支持全连接,可以通过联合左连接和右连接的结果来模拟全连接。

内连接(INNER JOIN)和全连接(FULL JOIN)是SQL中用于合并两个表的记录的两种不同的连接类型。下面我将通过具体的案例来解释这两种连接的区别和用法。

内连接(INNER JOIN)

内连接只返回两个表中匹配的记录。如果两个表中的连接条件不匹配,则不会返回结果。

案例

假设有两个表:studentscourses

  • students 表:

    CREATE TABLE students (
        student_id INT,
        student_name VARCHAR(100)
    );

    数据:

    student_id | student_name
    -------------------------
    1          | Alice
    2          | Bob
    3          | Carol
  • courses 表:

    CREATE TABLE courses (
        course_id INT,
        course_name VARCHAR(100),
        student_id INT
    );

    数据:

    course_id | course_name | student_id
    ------------------------------------
    101       | Math        | 1
    102       | Science     | 2
    103       | History     | 1

现在,如果我们想要找出选了课程的学生及其课程名称,可以使用内连接:

SELECT s.student_name, c.course_name
FROM students s
INNER JOIN courses c ON s.student_id = c.student_id;

结果:

student_name | course_name
-----------------------
Alice       | Math
Bob         | Science
Alice       | History

全连接(FULL JOIN)

全连接返回左表和右表中的所有记录。如果某一侧没有匹配的记录,则对应的列会用 NULL 填充。

案例

使用相同的 studentscourses 表。

SQL 查询

MySQL 不直接支持 FULL JOIN,但可以通过联合 LEFT JOINRIGHT JOIN 并使用 UNION 来模拟:

SELECT s.student_name, c.course_name
FROM students s
LEFT JOIN courses c ON s.student_id = c.student_id

UNION

SELECT s.student_name, c.course_name
FROM students s
RIGHT JOIN courses c ON s.student_id = c.student_id;
结果
student_name | course_name
-----------------------
Alice       | Math
Bob         | Science
Alice       | History
Carol       | NULL
NULL        | Math

在这个结果中:

  • Alice 和 Bob 出现在左侧和右侧的匹配结果中。

  • Carol 没有选任何课程,所以她的 course_nameNULL

  • 有一个课程没有学生选,所以 student_nameNULL

总结

  • 内连接:只返回匹配的记录,不匹配的记录不会出现在结果中。

  • 全连接:返回所有记录,不匹配的记录用 NULL 填充。

全连接在处理需要同时考虑两个表所有记录的场景中非常有用,尤其是在需要分析两个表中所有数据的完整性时。

NUION操作符

UNION 是 SQL 中的一个操作符,用于合并两个或多个 SELECT 语句的结果集,并返回唯一的记录。UNION 会自动去除重复的行(整行),只保留唯一的结果。

基本语法

SELECT column1, column2, ...
FROM table1
WHERE condition

UNION

SELECT column1, column2, ...
FROM table2
WHERE condition

示例

假设有两个表:employeesmanagers,我们想要合并这两个表中的所有员工信息。

  • employees 表:

    CREATE TABLE employees (
        employee_id INT,
        employee_name VARCHAR(100),
        department VARCHAR(100)
    );

    数据:

    employee_id | employee_name | department
    ---------------------------------------
    1           | Alice         | IT
    2           | Bob           | HR
  • managers 表:

    CREATE TABLE managers (
        manager_id INT,
        manager_name VARCHAR(100),
        department VARCHAR(100)
    );

    数据:

    manager_id | manager_name | department
    ---------------------------------------
    3          | Carol        | Finance
    4          | Dave         | Marketing

我们可以使用 UNION 来合并这两个表中的所有员工和经理的信息:

SELECT employee_id AS id, employee_name AS name, department
FROM employees
UNION
SELECT manager_id, manager_name, department
FROM managers;

结果:

id | name  | department
-------------------------
1  | Alice | IT
2  | Bob   | HR
3  | Carol | Finance
4  | Dave  | Marketing

注意事项

  1. 列数匹配:使用 UNION 时,每个 SELECT 语句中的列数必须相同。

  2. 列类型匹配:每个相应列的数据类型也必须兼容,例如,第一个查询的第二列是 VARCHAR 类型,那么第二个查询的第二列也应该是 VARCHAR 类型。

  3. 去重UNION 会自动去除重复的行,只保留唯一的结果。如果你想要保留所有行(包括重复的行),可以使用 UNION ALL

UNION ALL 示例

如果我们想要保留所有行,包括重复的行,可以使用 UNION ALL

SELECT employee_id AS id, employee_name AS name, department
FROM employees
UNION ALL
SELECT manager_id, manager_name, department
FROM managers;

如果 employeesmanagers 表中有重复的记录,UNION ALL 会保留这些重复的行。

总结

UNION 是一个非常有用的操作符,用于合并多个查询的结果集,并自动去除重复的行。使用 UNION ALL 可以保留所有行,包括重复的行。在实际应用中,根据需求选择合适的操作符。

  • 13
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

唯手熟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值