0

0

SQL的LEFTJOIN与RIGHTJOIN有何区别?连接类型的解析

蓮花仙者

蓮花仙者

发布时间:2025-09-05 14:59:01

|

776人浏览过

|

来源于php中文网

原创

LEFT JOIN保留左表所有行,右表无匹配时填NULL;RIGHT JOIN反之,保留右表所有行,左表无匹配时填NULL;两者功能对称,但LEFT JOIN更常用,因习惯以左表为主表,RIGHT JOIN可通过调换表序用LEFT JOIN实现,实践中为统一风格常只用LEFT JOIN。

sql的leftjoin与rightjoin有何区别?连接类型的解析

SQL的

LEFT JOIN
RIGHT JOIN
在功能上是镜像对称的,它们的核心区别在于哪个表的数据被视为“主导”或“保留”的。简单来说,
LEFT JOIN
会保留左表的所有行,即使右表中没有匹配项也会显示,右表对应位置则为NULL;而
RIGHT JOIN
则反之,它会保留右表的所有行,左表没有匹配项时显示NULL。它们解决的是“我需要哪些数据作为基础,然后去匹配其他数据”的问题。

解决方案

在SQL的世界里,连接(JOIN)操作是数据整合的基石,而

LEFT JOIN
RIGHT JOIN
则是其中的两个关键工具。理解它们的运作方式,对于构建准确且高效的查询至关重要。

LEFT JOIN(左连接)

LEFT JOIN
,顾名思义,是以左边的表(FROM子句中列出的第一个表)为基准。它会返回左表中的所有行,无论这些行在右表中是否有匹配的数据。如果右表中存在与左表匹配的行,那么这些匹配的行数据也会被包含进来。但如果左表中的某一行在右表中找不到任何匹配项,那么右表对应的所有列都将显示为
NULL

这在实际应用中非常有用。比如,你可能想查看所有客户的信息,以及他们下过的所有订单。即使有些客户从未下过订单,你仍然希望在结果中看到他们,只是他们的订单信息会是空的。

示例:

假设我们有两个表:

Customers
(包含
CustomerID
,
CustomerName
) 和
Orders
(包含
OrderID
,
CustomerID
,
OrderDate
)。

SELECT
    c.CustomerID,
    c.CustomerName,
    o.OrderID,
    o.OrderDate
FROM
    Customers c
LEFT JOIN
    Orders o ON c.CustomerID = o.CustomerID;

这个查询会列出所有客户,包括那些没有下过订单的客户。对于没有订单的客户,

OrderID
OrderDate
列将显示
NULL

RIGHT JOIN(右连接)

RIGHT JOIN
LEFT JOIN
的操作逻辑完全相反。它以右边的表为基准,返回右表中的所有行。如果左表中存在与右表匹配的行,这些匹配的行数据也会被包含。如果右表中的某一行在左表中找不到任何匹配项,那么左表对应的所有列都将显示为
NULL

虽然功能上与

LEFT JOIN
对称,但
RIGHT JOIN
在实践中相对较少使用,因为大多数开发者习惯于将“主”表放在
FROM
子句中,然后通过
LEFT JOIN
去关联其他表。不过,这并不意味着它没有用武之地。有时,从逻辑上讲,右表可能才是你真正想要“保留”所有数据的核心。

示例:

继续使用上面的

Customers
Orders
表。

SELECT
    c.CustomerID,
    c.CustomerName,
    o.OrderID,
    o.OrderDate
FROM
    Customers c
RIGHT JOIN
    Orders o ON c.CustomerID = o.CustomerID;

这个查询会列出所有订单,包括那些可能没有对应客户信息的订单(这通常意味着数据异常或数据录入错误)。对于没有对应客户的订单,

CustomerID
(来自Customers表)和
CustomerName
将显示
NULL

为什么我们更常看到LEFT JOIN,RIGHT JOIN是不是不那么重要?

这其实是个很有趣的现象,我个人觉得它更多地反映了人类的思维习惯和阅读流程。我们习惯从左到右阅读,在编写SQL查询时,自然而然地会将我们认为“主要”或“起始”的表放在

FROM
子句中,作为我们关注的焦点。接着,我们用
LEFT JOIN
去“拉取”或“扩展”与这个主要表相关的数据。这种模式符合我们从一个核心实体出发,逐步探索其周边信息的逻辑。

RIGHT JOIN
在功能上与
LEFT JOIN
是完全等价的,你总能通过交换
FROM
JOIN
子句中的表顺序,将一个
RIGHT JOIN
改写成
LEFT JOIN
。例如:

-- 原始 RIGHT JOIN
SELECT * FROM TableA RIGHT JOIN TableB ON TableA.id = TableB.id;

-- 等价的 LEFT JOIN
SELECT * FROM TableB LEFT JOIN TableA ON TableA.id = TableB.id;

所以,

RIGHT JOIN
并非不重要,它只是在实践中较少被直接使用。它的存在,更多是出于语言的完整性和对称性考虑。在团队协作中,为了保持代码风格的一致性和可读性,许多团队甚至会约定只使用
LEFT JOIN
。这并非技术上的限制,而是一种工程上的最佳实践,旨在减少认知负担和潜在的错误。如果你在维护一个遗留系统,或者遇到一个特定场景下
RIGHT JOIN
能让逻辑更清晰的查询,当然也可以使用它。但就我个人经验而言,我几乎总是倾向于用
LEFT JOIN
,并通过调整表顺序来达到目的。

在实际数据分析中,如何选择合适的JOIN类型以避免数据丢失或冗余?

选择正确的

JOIN
类型是数据分析中至关重要的一步,它直接决定了你的结果集的完整性和准确性。避免数据丢失或冗余,关键在于你首先要清晰地定义你的分析目标和数据需求。

  • 明确你的“主”数据集: 问自己,我希望以哪个表的数据为基础?哪个表的数据是无论如何都不能丢弃的?一旦确定了这个“主”表,它通常就是你

    FROM
    子句中的第一个表。如果你希望保留这个“主”表的所有记录,即使它在其他表中没有匹配项,那么
    LEFT JOIN
    就是你的首选。例如,如果你想分析所有产品的销售情况,即使有些产品本月没有销量,你仍然希望它们出现在报表中,那么
    Products
    表就是你的“主”表,然后
    LEFT JOIN
    Sales
    表。

    Figma
    Figma

    Figma 是一款基于云端的 UI 设计工具,可以在线进行产品原型、设计、评审、交付等工作。

    下载
  • 理解连接条件:

    ON
    子句中的条件是连接的灵魂。错误的连接条件会导致大量不匹配、重复数据甚至笛卡尔积。确保你连接的列是逻辑上相关且具有唯一性或接近唯一性的键(如主键、外键)。

  • 避免数据丢失(不完整的结果):

    • 如果你需要所有左表记录及其匹配的右表记录,使用
      LEFT JOIN
    • 如果你需要所有右表记录及其匹配的左表记录,使用
      RIGHT JOIN
      (或者更常见的,调换表顺序使用
      LEFT JOIN
      )。
    • 如果你只需要两个表中都存在的匹配记录,那么
      INNER JOIN
      是正确的选择。使用
      INNER JOIN
      时,任何不匹配的记录都会被丢弃。
  • 避免数据冗余(重复的结果):

    • 一对多关系: 这是最常见的导致“冗余”的场景。当你的“主”表中的一行在被连接的表中有多行匹配时(例如,一个客户有多笔订单),
      JOIN
      操作会为每一笔匹配的订单重复显示客户信息。这本身不是错误,而是
      JOIN
      的正常行为。
      • 解决方案: 如果你只关心客户信息,而不想因为订单数量而重复客户,你可能需要在使用
        JOIN
        之后,再使用
        DISTINCT
        关键字(
        SELECT DISTINCT c.CustomerID, c.CustomerName FROM ...
        )或者聚合函数(如
        COUNT(o.OrderID)
        ,然后
        GROUP BY c.CustomerID
        )。
    • 多对多关系: 如果两个表之间存在多对多关系,并且你直接进行
      JOIN
      ,结果集会非常庞大且可能难以解释。通常,多对多关系通过一个“连接表”或“中间表”来解决。
    • 错误的连接条件: 如果
      ON
      子句中的条件不够精确,导致一个左表行匹配到多个不相关的右表行,也会产生大量冗余。仔细检查你的
      ON
      条件,确保它准确地反映了你想要连接的逻辑。

总而言之,选择

JOIN
类型是一个迭代的过程。从你的分析目标出发,选择最能反映你数据保留策略的
JOIN
,然后通过检查结果集来验证其准确性。不要害怕尝试不同的
JOIN
类型,并观察它们如何影响你的数据。

除了LEFT JOIN和RIGHT JOIN,还有哪些SQL连接类型及其适用场景?

SQL的连接类型远不止

LEFT JOIN
RIGHT JOIN
,它们共同构成了数据整合的强大工具箱。理解每种连接的特性及其适用场景,能让你在数据查询时更加得心应手。

1. INNER JOIN(内连接)

这是最常用也最基本的连接类型。

INNER JOIN
只返回那些在两个连接表中都存在匹配关系的行。任何在任一表中没有匹配项的行都会被排除在结果集之外。

  • 适用场景: 当你只需要两个表中都有对应数据的记录时。例如,你想查看所有已经下过订单的客户信息,或者所有有员工分配的部门列表。
  • 示例:
    SELECT
        c.CustomerName,
        o.OrderID
    FROM
        Customers c
    INNER JOIN
        Orders o ON c.CustomerID = o.CustomerID;

    这个查询只会返回那些既在

    Customers
    表中有记录,又在
    Orders
    表中有订单的客户及其订单信息。没有订单的客户和没有对应客户的订单都不会出现在结果中。

2. FULL OUTER JOIN(全外连接)

FULL OUTER JOIN
LEFT JOIN
RIGHT JOIN
的结合体。它会返回左表和右表中的所有行。如果某一行在另一个表中没有匹配项,那么对应列的值将显示为
NULL

  • 适用场景: 当你需要查看两个数据集的所有记录,包括它们共同的部分,以及各自独有的部分时。例如,比较两个不同来源的产品目录,找出共同的产品、只存在于第一个目录的产品和只存在于第二个目录的产品。
  • 示例:
    SELECT
        c.CustomerName,
        o.OrderID
    FROM
        Customers c
    FULL OUTER JOIN
        Orders o ON c.CustomerID = o.CustomerID;

    这个查询会列出所有客户(无论是否有订单)和所有订单(无论是否有对应客户)。如果客户没有订单,

    OrderID
    NULL
    ;如果订单没有客户,
    CustomerName
    NULL

3. CROSS JOIN(交叉连接)

CROSS JOIN
会生成两个连接表的笛卡尔积。这意味着左表的每一行都会与右表的每一行进行组合。如果左表有M行,右表有N行,结果集将有M * N行。
CROSS JOIN
通常不使用
ON
子句,因为它不基于任何匹配条件。

  • 适用场景: 相对较少直接使用,但当需要生成所有可能的组合时非常有用。例如,生成所有产品颜色和尺寸的组合,或者在某些数据生成和测试场景中。
  • 示例:
    SELECT
        p.ProductName,
        s.SizeName
    FROM
        Products p
    CROSS JOIN
        Sizes s;

    如果

    Products
    表有10个产品,
    Sizes
    表有5种尺寸,结果将有50行,列出每个产品与每种尺寸的组合。

4. SELF JOIN(自连接)

SELF JOIN
并不是一个独立的
JOIN
关键字,而是一种连接表的方式。它是指一个表与它自身进行连接。为了区分同一个表的两个实例,必须使用表别名。

  • 适用场景: 当你需要在同一个表中查找相关联的行时。例如,在一个员工表中查找哪些员工是彼此的经理和下属关系,或者在一个分类表中查找父子分类关系。
  • 示例:
    SELECT
        e1.EmployeeName AS Employee,
        e2.EmployeeName AS Manager
    FROM
        Employees e1
    INNER JOIN
        Employees e2 ON e1.ManagerID = e2.EmployeeID;

    这个查询会列出每个员工及其对应的经理,假设

    Employees
    表有一个
    ManagerID
    列指向另一个员工的
    EmployeeID

理解这些不同的

JOIN
类型,并根据你的数据结构和查询目标灵活运用它们,是掌握SQL数据查询能力的关键。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

707

2023.10.12

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

327

2023.10.27

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

350

2024.02.23

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

1221

2024.03.06

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

360

2024.03.06

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

819

2024.04.07

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

581

2024.04.29

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

423

2024.04.29

Python 自然语言处理(NLP)基础与实战
Python 自然语言处理(NLP)基础与实战

本专题系统讲解 Python 在自然语言处理(NLP)领域的基础方法与实战应用,涵盖文本预处理(分词、去停用词)、词性标注、命名实体识别、关键词提取、情感分析,以及常用 NLP 库(NLTK、spaCy)的核心用法。通过真实文本案例,帮助学习者掌握 使用 Python 进行文本分析与语言数据处理的完整流程,适用于内容分析、舆情监测与智能文本应用场景。

22

2026.01.27

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Rust 教程
Rust 教程

共28课时 | 4.9万人学习

Kotlin 教程
Kotlin 教程

共23课时 | 2.9万人学习

Go 教程
Go 教程

共32课时 | 4.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号