MySQL LEFT JOIN

摘要:在本教程中,您将了解 MySQL LEFT JOIN子句以及如何应用它来查询两个或多个表中的数据。

MySQL LEFT JOIN 子句简介

LEFT JOIN允许您从两个或多个表查询数据。与INNER JOIN子句类似, LEFT JOINSELECT语句的可选子句,它紧跟在FROM子句之后。

假设您要连接两个表t1t2

以下语句显示如何使用LEFT JOIN子句连接两个表:

SELECT 
    select_list
FROM
    t1
LEFT JOIN t2 ON 
    join_condition;Code language: SQL (Structured Query Language) (sql)

当使用LEFT JOIN子句时,引入了左表和右表的概念。

在上面的语法中, t1是左表, t2是右表。

LEFT JOIN子句从左表 ( t1 ) 开始选择数据。它根据join_condition将左表 ( t1 ) 中的每一行与右表 ( t2 ) 中的每一行进行匹配。

如果两个表中的行导致联接条件计算为true ,则LEFT JOIN会将两个表中的行列合并为一个新行,并将该新行包含在结果行中。

如果左表 ( t1 ) 中的行与右表 ( t2 ) 中的任何行都不匹配,则LEFT JOIN仍将两个表中的行列组合成新行,并将新行包含在结果行中。但是,它对右表中该行的所有列使用NULL

换句话说, LEFT JOIN返回左表中的所有行,无论左表中的行是否具有右表中的匹配行。

如果没有匹配,则右表中的行的列将包含NULL

以下维恩图可帮助您直观地了解LEFT JOIN子句的工作原理:

MySQL LEFT JOIN - 维恩图
MySQL LEFT JOIN – 维恩图

MySQL LEFT JOIN 子句示例

让我们举一些使用LEFT JOIN子句的示例。

1)使用MySQL LEFT JOIN子句连接两个表

请参阅示例数据库中的下表customersorders

每个客户可以有零个或多个订单,而每个订单必须属于一个客户。

此查询使用LEFT JOIN子句来查找所有客户及其订单:

SELECT 
    customers.customerNumber, 
    customerName, 
    orderNumber, 
    status
FROM
    customers
LEFT JOIN orders ON 
    orders.customerNumber = customers.customerNumber;Code language: SQL (Structured Query Language) (sql)

或者,您可以使用表别名来节省一些输入:

SELECT
    c.customerNumber,
    customerName,
    orderNumber,
    status
FROM
    customers c
LEFT JOIN orders o 
    ON c.customerNumber = o.customerNumber;Code language: SQL (Structured Query Language) (sql)
MySQL LEFT JOIN example

在这个例子中:

  • 左表是customers ,右表是orders
  • LEFT JOIN子句返回所有客户,包括没有订单的客户。如果客户没有订单,则orderNumberstatus列中的值为NULL

由于表 Customers 和 Orders 在使用 equal 运算符的连接条件中具有相同的列名 ( customerNumber ),因此您可以使用 USING 语法,如下所示:

SELECT
	customerNumber,
	customerName,
	orderNumber,
	status
FROM
	customers
LEFT JOIN orders USING (customerNumber);Code language: SQL (Structured Query Language) (sql)

以下子句是等效的:

USING (customerNumber)Code language: SQL (Structured Query Language) (sql)

ON c.customerNumber = o.customerNumberCode language: SQL (Structured Query Language) (sql)

如果将LEFT JOIN子句替换为INNER JOIN子句,您将获得唯一至少拥有一个订单的客户。

2)使用MySQL LEFT JOIN子句查找不匹配的行

当您想要查找一个表中没有另一个表中的匹配行的行时, LEFT JOIN子句非常有用。

以下示例使用LEFT JOIN查找没有订单的客户:

SELECT 
    c.customerNumber, 
    c.customerName, 
    o.orderNumber, 
    o.status
FROM
    customers c
LEFT JOIN orders o 
    ON c.customerNumber = o.customerNumber
WHERE
    orderNumber IS NULL;Code language: SQL (Structured Query Language) (sql)
MySQL LEFT JOIN unmatched rows

3)使用MySQL LEFT JOIN连接三个表

请参阅以下三个表employeescustomerspayments

此示例使用两个LEFT JOIN子句来连接三个表: employeescustomerspayments

SELECT 
    lastName, 
    firstName, 
    customerName, 
    checkNumber, 
    amount
FROM
    employees
LEFT JOIN customers ON 
    employeeNumber = salesRepEmployeeNumber
LEFT JOIN payments ON 
    payments.customerNumber = customers.customerNumber
ORDER BY 
    customerName, 
    checkNumber;
Code language: SQL (Structured Query Language) (sql)

这张图显示了部分输出:

MySQL LEFT JOIN 三表示例

怎么运行的。

  • 第一个LEFT JOIN返回代表每个员工的所有员工和客户,如果该员工不负责任何客户,则返回NULL
  • 第二个LEFT JOIN返回由员工代表的每个客户的付款,如果客户没有付款,则返回NULL

WHERE子句中的条件与ON子句中的条件

请参阅以下示例。

SELECT 
    o.orderNumber, 
    customerNumber, 
    productCode
FROM
    orders o
LEFT JOIN orderDetails 
    USING (orderNumber)
WHERE
    orderNumber = 10123;
Code language: SQL (Structured Query Language) (sql)

此示例使用LEFT JOIN子句从表ordersorderDetails中查询数据。查询返回订单号10123的订单及其行项。

MySQL LEFT JOIN - Condition in WHERE clause

但是,如果将条件从WHERE子句移至ON子句:

SELECT 
    o.orderNumber, 
    customerNumber, 
    productCode
FROM
    orders o
LEFT JOIN orderDetails d 
    ON o.orderNumber = d.orderNumber AND 
       o.orderNumber = 10123;Code language: SQL (Structured Query Language) (sql)

将会有不同的意义。

在这种情况下,查询返回所有订单,但只有订单10123有与其关联的订单项,如下图所示:

MySQL LEFT JOIN - Condition in ON clause

请注意,对于INNER JOIN子句, ON子句中的条件与WHERE子句中的条件等效。

在本教程中,您学习了如何使用 MySQL LEFT JOIN子句连接两个或多个表中的数据。

本教程有帮助吗?