自学内容网 自学内容网

mysql学习教程,从入门到精通,SQL LEFT JOIN 语句(23)

1、SQL LEFT JOIN 语句

在SQL中,LEFT JOIN(也称为左连接)是一种将左表(LEFT JOIN左侧的表)的所有记录与右表(LEFT JOIN右侧的表)中匹配的记录结合起来的查询方式。如果左表中的记录在右表中没有匹配,则结果中这些记录的右表部分将包含NULL。这非常有用,尤其是当你想要从一个表中获取所有记录,并且想要获取与之相关联的另一个表中的信息(如果存在的话)时。
下面是一个简单的LEFT JOIN语句的示例。假设我们有两个表:employees(员工表)和departments(部门表)。employees表有一个department_id字段,它引用了departments表中的id字段。
employees 表结构

idnamedepartment_id
1Alice1
2Bob2
3Charlie3

departments 表结构

idname
1HR
2Engineering

我们想要查询所有员工及其对应的部门名称,即使某些员工没有分配部门(即department_iddepartments表中没有对应的记录)。

SQL LEFT JOIN 语句

SELECT employees.name AS employee_name, departments.name AS department_name  
FROM employees  
LEFT JOIN departments ON employees.department_id = departments.id;

这条SQL语句会返回以下结果:

employee_namedepartment_name
AliceHR
BobEngineering
CharlieNULL

在这个结果中,Alice和Bob都成功匹配到了他们所属的部门名称,而Charlie在departments表中没有对应的department_id,因此他的department_name显示为NULL。这正是LEFT JOIN的作用所在:它确保了左表(employees)中的所有记录都会出现在结果中,即使它们在右表(departments)中没有匹配项。
当然可以。以下是一个更实际的LEFT JOIN案例,假设我们在运营一个在线书店,并且有两个主要的数据库表:orders(订单表)和customers(客户表)。我们想要查询所有订单的信息,包括下单的客户名称,即使某些订单可能还没有关联到具体的客户(虽然这在现实中不太常见,但可以作为示例来说明LEFT JOIN的用法)。
orders 表结构

order_idcustomer_idorder_datetotal_amount
112023-01-01100.00
222023-01-02150.00
3NULL2023-01-0350.00

customers 表结构

customer_idnameemail
1John Doejohn.doe@example.com
2Jane Smithjane.smith@example.com

现在,我们想要查询所有订单的信息,包括每个订单的客户名称(如果有的话)。由于订单3没有customer_id,我们将使用LEFT JOIN来确保这个订单也出现在结果中,并且客户名称将为NULL。

SQL LEFT JOIN 语句

SELECT   
    orders.order_id,  
    orders.order_date,  
    orders.total_amount,  
    customers.name AS customer_name  
FROM   
    orders  
LEFT JOIN   
    customers ON orders.customer_id = customers.customer_id;

这条SQL语句会返回以下结果:

order_idorder_datetotal_amountcustomer_name
12023-01-01100.00John Doe
22023-01-02150.00Jane Smith
32023-01-0350.00NULL

即使订单3没有关联的客户(customer_id为NULL),它也出现在了结果中,并且customer_name列显示为NULL。这正是LEFT JOIN在处理此类场景时的优势所在。
当然可以,为了提供一个更复杂的LEFT JOIN案例,我们可以考虑一个涉及三张表的场景:一个在线书店的订单系统。这个系统包括orders(订单表)、customers(客户表)和books(书籍表)。我们的目标是查询每个订单的信息,包括订单ID、订单日期、总金额、客户名称以及所购买的书籍名称,即使某些订单可能只包含部分书籍信息(假设有些订单信息尚未完全录入书籍信息)。
表结构概述

  1. orders 表

    • order_id: 订单ID
    • customer_id: 客户ID
    • order_date: 订单日期
    • total_amount: 总金额
  2. customers 表

    • customer_id: 客户ID
    • name: 客户名称
    • email: 电子邮件
  3. order_details 表

    (新增表,用于存储订单中的书籍详情)

    • detail_id: 详情ID
    • order_id: 订单ID
    • book_id: 书籍ID
    • quantity: 数量

books 表

  • book_id: 书籍ID
  • title: 书籍名称
  • author: 作者
    在这个案例中,我们需要将orders表与customers表进行LEFT JOIN以获取订单的客户信息,然后再将结果与order_details表和books表进行连接以获取书籍信息。但是,由于我们想要直接显示书籍名称而不是通过order_details表间接获取(因为那样会得到重复的订单信息),我们需要使用子查询或临时表来优化查询。不过,为了保持示例的简洁性,这里我将展示一个使用多次LEFT JOIN的查询,尽管它可能不是最优的解决方案。
    SQL LEFT JOIN 语句(简化版,可能不是最优)
SELECT   
    o.order_id,  
    o.order_date,  
    o.total_amount,  
    c.name AS customer_name,  
    bd.book_id,  
    b.title AS book_title  
FROM   
    orders o  
LEFT JOIN   
    customers c ON o.customer_id = c.customer_id  
LEFT JOIN   
    order_details bd ON o.order_id = bd.order_id  
LEFT JOIN   
    books b ON bd.book_id = b.book_id;

注意

  • 这个查询可能会为每个订单中的每本书生成一行结果,如果你想要的是每个订单的汇总信息(例如,所有书籍的名称以某种方式聚合),你可能需要使用GROUP_CONCAT(在MySQL中)或其他字符串聚合函数,或者将查询结果作为子查询进一步处理。
  • 在实际应用中,如果订单与书籍之间是多对多的关系(即一个订单可以包含多本书,一本书也可以出现在多个订单中),并且你想要避免结果中的重复订单信息,你可能需要使用GROUP BY子句结合聚合函数来整理结果。
    更复杂的处理(假设需要聚合书籍名称)
    如果你想要的是每个订单及其对应的所有书籍名称(以逗号分隔或其他方式聚合),你可以使用MySQL的GROUP_CONCAT函数,如下所示:
SELECT   
    o.order_id,  
    o.order_date,  
    o.total_amount,  
    c.name AS customer_name,  
    GROUP_CONCAT(b.title SEPARATOR ', ') AS book_titles  
FROM   
    orders o  
LEFT JOIN   
    customers c ON o.customer_id = c.customer_id  
LEFT JOIN   
    order_details bd ON o.order_id = bd.order_id  
LEFT JOIN   
    books b ON bd.book_id = b.book_id  
GROUP BY   
    o.order_id;

这个查询将每个订单的书籍名称聚合为一个由逗号分隔的字符串,并返回每个订单的汇总信息。


原文地址:https://blog.csdn.net/qq_45746668/article/details/142471313

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!