当前位置: 首页 > article >正文

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

1、SQL FULL JOIN 语句

在SQL中,FULL JOIN(也被称为全外连接)是一种结合了两个表中的所有行的操作,包括两个表中匹配的行以及那些不匹配的行。如果在一个表中有行在另一个表中没有匹配,那么这些行将出现在结果集中,但是与之不匹配的列的值将是NULL
下面是一个使用FULL JOIN语句的例子。假设我们有两个表:employees(员工表)和departments(部门表)。employees表包含员工的ID、姓名和所属部门ID,而departments表包含部门ID和部门名称。
employees 表结构示例:

employee_idnamedepartment_id
1Alice101
2Bob102
3Carol103

departments 表结构示例:

department_iddepartment_name
101HR
102IT
104Finance

如果我们想要查询所有员工及其所属部门,包括那些没有员工的部门(如Finance),以及那些不属于任何已知部门(在我们的示例中不存在,但理论上可能)的员工,我们可以使用FULL JOIN
SQL查询语句如下:

SELECT 
    employees.name AS EmployeeName,
    departments.department_name AS DepartmentName
FROM 
    employees
FULL JOIN 
    departments ON employees.department_id = departments.department_id
ORDER BY 
    COALESCE(employees.name, departments.department_name);

注意几个关键点:

  1. FULL JOIN的使用:它确保了从两个表中返回所有行。如果employees表中的某行在departments表中没有匹配的department_id,则结果中该行的department_name将为NULL。反之亦然。
  2. COALESCE函数:在ORDER BY子句中,我们使用了COALESCE函数来确保排序能够顺利进行,即使某些列是NULLCOALESCE返回其参数列表中的第一个非空表达式。这里,它确保了如果EmployeeNameNULL(意味着该行来自departments表且没有对应的员工),则使用DepartmentName进行排序。然而,在这个特定的例子中,由于我们想要根据员工名或部门名进行排序,而这个逻辑可能需要更复杂的逻辑来确保顺序的合理性(比如,先按部门名排序,再按员工名排序,但只针对有值的行),这里仅作为展示COALESCE函数的一个用法。
  3. 实际排序需求:根据实际需求,你可能需要调整排序逻辑或移除ORDER BY子句,特别是如果你不需要特定的排序顺序。
  4. 结果集:结果集将包括所有员工及其对应的部门名(如果存在),以及所有没有员工的部门名(如Finance)。对于没有对应部门的员工(在上面的示例中不存在),理论上也将包含,但在实际情况下,如果数据库设计得当,这种情况应该很少见。

当然可以,以下是一些具体的SQL FULL JOIN 案例,这些案例将帮助您更好地理解FULL JOIN的工作原理。

案例1:员工与部门

场景
假设我们有两个表,employees(员工表)和departments(部门表)。我们需要列出所有员工及其所属部门,包括那些没有分配部门的员工和没有员工的部门。
employees 表

employee_idnamedepartment_id
1Alice101
2Bob102
3CarolNULL

departments 表

department_iddepartment_name
101HR
102IT
103Finance

SQL 查询

SELECT   
    employees.name AS EmployeeName,  
    departments.department_name AS DepartmentName  
FROM   
    employees  
FULL JOIN   
    departments ON employees.department_id = departments.department_id;

结果

EmployeeNameDepartmentName
AliceHR
BobIT
CarolNULL
NULLFinance

这个查询返回了所有员工和部门,包括Carol(没有部门)和Finance(没有员工)。

案例2:订单与客户

场景
我们有两个表,orders(订单表)和customers(客户表)。我们需要查看所有订单及其对应的客户,包括那些没有关联到任何客户的订单。
customers 表

customer_idname
1John
2Jane

orders 表

order_idcustomer_idorder_date
10112023-01-01
10222023-01-02
103NULL2023-01-03

SQL 查询

SELECT   
    customers.name AS CustomerName,  
    orders.order_id,  
    orders.order_date  
FROM   
    customers  
FULL JOIN   
    orders ON customers.customer_id = orders.customer_id;

结果

CustomerNameorder_idorder_date
John1012023-01-01
Jane1022023-01-02
NULL1032023-01-03

这个查询返回了所有订单和客户,包括订单103(没有关联到任何客户)。

案例3:学生成绩

场景
我们有两个表,students(学生表)和grades(成绩表)。我们需要列出所有学生的成绩,包括那些没有成绩的学生。
students 表

student_idname
1Alice
2Bob
3Carol

grades 表

grade_idstudent_idscore
1190
2285

SQL 查询

SELECT   
    students.name AS StudentName,  
    grades.score  
FROM   
    students  
FULL JOIN   
    grades ON students.student_id = grades.student_id;

注意:在实际应用中,由于FULL JOIN可能会产生重复的行(尽管在这个特定案例中不会),并且MySQL等某些数据库不支持FULL JOIN,我们通常会使用LEFT JOIN结合UNIONCOALESCE等函数来达到类似的效果。但为了直接展示FULL JOIN的用途,这里假设我们使用的数据库支持FULL JOIN
然而,为了兼容性,我们可以使用LEFT JOINUNION来模拟FULL JOIN的效果:

SELECT   
    students.name AS StudentName,  
    grades.score  
FROM   
    students  
LEFT JOIN   
    grades ON students.student_id = grades.student_id  
UNION  
SELECT   
    students.name,  
    NULL AS score  
FROM   
    students  
RIGHT JOIN   
    grades ON students.student_id = grades.student_id  
WHERE   
    students.student_id IS NULL;

但请注意,上面的RIGHT JOIN部分实际上是多余的,因为LEFT JOIN已经覆盖了所有情况。正确的模拟应该是只使用LEFT JOIN加上对grades表中未匹配记录的单独查询(如果有的话,但在这个案例中不需要),但这里为了展示目的而包含了它。

对于支持FULL JOIN的数据库,原始FULL JOIN查询的结果将是:

StudentNamescore
Alice90
Bob85
CarolNULL

这个查询返回了所有学生及其成绩,包括Carol(没有成绩)。


http://www.kler.cn/news/319825.html

相关文章:

  • mysql离线脚本安装
  • 【C++算法】哈希表
  • vs2022 程序包管理器控制台中文乱码
  • 100个ChatGPT学术指令—助你高效完成文献综述撰写!
  • 深入理解同步和异步与reactor和proactor模式
  • 【递归】5.leetcode 872 叶子相似的树
  • 南开大学联合同济大学发布最新SOTA Occ OPUS:使用稀疏集进行占据预测,最快实现8帧22FPS
  • 什么是服务器日志,日志有什么作用?
  • 2-103 基于matlab的光电信号下血氧饱和度计算
  • Unity3D URP 内置CSM分帧详解
  • 【渗透测试】-灵当CRM系统-sql注入漏洞复现
  • 传输层协议 —— TCP协议(下篇)
  • Spring IoC DI 之 属性注入
  • BottomNavigationView 添加角标
  • c++开发实战之网络编程(一)
  • 三维重建的几何评价指标
  • 面试算法题精讲:求数组两组数差值和的最大值
  • 只出现一次的数字 II
  • Redis:事务
  • Hive 的窗口函数 详解
  • 代码随想录算法训练营| 454.四数相加II 、 383. 赎金信 、 15. 三数之和 、 18. 四数之和
  • 有威胁的武器武装检测系统源码分享
  • WebGL渲染与创建2D内容
  • 树——数据结构
  • 移动端如何实现智能语音交互
  • 【LGR-200-Div.4】洛谷入门赛 #27 A - H题解,包含(C++, Go语言)
  • Mybatis中sql数组为空判断
  • SpringBoot 整合docker,执行容器服务
  • Qt系统相关——事件
  • JavaScript --模版字符串用反引号