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

SQL学习指南——再谈连接

外连接

到目前为止,所有的示例都包括多个数据表,我们并没有考虑过连接条件可能无法为数据表中的所有行找到匹配,例如,inventory数据表中的每行包含的都是一部可供租借的电影,但是film数据表中的1000部电影(1000行)中只有958部在inventory数据表中有一行或多行,其余42部电影不能用于租借,所以这些电影的ID无法在inventory数据表中找到,下列查询通过连接这两个数据表,统计每部电影可用的拷贝数量



由于查询使用的是内连接,只返回满足连接条件的行,所以只返回了958行,如果希望查询返回所有的1000部电影,而不管在inventory数据表中有没有对应的行,那么可以使用外连接,使连接条件成为可选的


从上述结果中可以看出,该查询返回了film数据表的全部1000行

下面描述了对该查询的改动:

  1. 将连接定义从inner改为left outer,指示服务器包含该连接左侧数据表的所有行
  2. cnt列的定义从count(*)改为count(i.inventory_id),后者统计inventory.inventory_id列值为非null的数量

左外连接与右外连接

计算left outer join结果集的行数,核心逻辑就是看左表的每一行在右表“命中”了多少次

可以把它想象成一次逐行的配对过程,数据库会从左表拿出第一行数据,去右表中寻找所有符合连接条件(on后面的规则)的记录

如果右表有N条记录能和它匹配,这一行就会在结果集中产生N条结果
如果右表一条都匹配不上(也就是0条),为了保证左表数据不丢失,它会强行产生1条结果,只不过右边对应的字段全是null

因此,结果集的总行数可以用一个简单的公式来概括
结果集总行数 = Σ (左表每行在右表中的实际匹配次数)
注意:这里的实际匹配次数有一个保底规则,最少算作1次

在上面的示例中指定的是left outer join,也可以指定right outer join
这两个查询执行的都是外连接。因为很少(如果有的话)会遇到右外连接,而且也不是所有的数据库服务器都支持这种连接,因此推荐使用左外连接,outer关键字是可选的,不过出于清晰性的考虑,最好还是加上outer

交叉连接

笛卡尔积本质上就是在未指定任何连接条件的情况下的多数据表连接的结果,笛卡尔集经常会偶然用到(比如,忘记在from子句中添加连接条件),但是使用频率并不高,如果确实打算生成两个数据表的笛卡尔积,应该指定交叉连接(cross join)

该查询生成数据表category和language的笛卡尔积,共计96行(category数据表16行 * language数据表6行)

自然连接

可以选择一种连接类型,其允许命名要连接的数据表,但是由数据库服务器决定需要什么样的连接条件,这种连接类型被称为自然连接(natural join),它依靠多个数据表之间相同的列名来推断适合的连接条件

核心逻辑:自动寻找两张表中同名的列,强制让它们相等进行匹配,并且在最终结果里把重复的列合并成一份

如果两张表中有两个或更多同名的列,自然连接(Natural Join)会触发一个非常隐蔽的“连坐”机制:它会把所有的同名列都自动加入连接条件,并且要求这些列的值必须同时相等

假设我们有两个表:员工表(employees) 和 部门表(departments)。
它们原本通过 dept_id(部门ID)关联,但刚好两张表里都有一个同名的记录时间的字段 created_at(创建时间)。
当你执行 SELECT * FROM employees NATURAL JOIN departments; 时,数据库在后台默默执行的逻辑等价于:

SELECT * FROM employees INNER JOIN departments ON employees.dept_id=departments.dept_id AND employees.created_at=departments.created_at;-- 👈 灾难现场!

那么,为了省事而不输入连接条件到底值不值得呢?绝对不值得,应该避免使用这种连接类型,而使用带有显式连接条件的内连接

http://www.jsqmd.com/news/866700/

相关文章:

  • Linux内核调度器心跳机制:scheduler_tick原理与性能调优
  • 新能源动力域系统级测试:从HIL仿真到自动化验证的完整解决方案
  • 基于EsDA平台实现串口设备联网:Modbus RTU转MQTT网关实战
  • Display Driver Uninstaller:彻底解决显卡驱动问题的3步终极指南
  • RISC-V嵌入式AI部署实战:NanoDet模型与ncnn框架移植指南
  • LangGraph实战:构建可控、可调试的复杂AI工作流
  • 抖音下载器:如何永久保存你喜欢的短视频内容?
  • 开源项目功能扩展技术方案:实现多账户管理与配置优化的完整指南
  • 抖音无水印下载终极指南:douyin-downloader让内容保存变得如此简单
  • 深入Linux调度器心跳:scheduler_tick原理、性能影响与调优实践
  • 网盘直链下载助手实战指南:八大平台免登录高速下载完整方案
  • 基于Linux内核list.h思想实现高效C语言单向链表
  • 专业鼠标加速配置指南:Raw Accel内核级驱动深度解析与实战优化策略
  • OpenRGB终极指南:一个软件统一控制所有RGB设备,告别厂商软件依赖
  • iOS 17.6.1系统更新深度解析:错误修复、安全加固与升级指南
  • Windows 10 21H1更新解析:聚焦混合办公安全与IT管理优化
  • Windows下OpenCore引导盘制作:5步打造完美Hackintosh启动盘
  • Python 爬虫实战:京东商品价格监控爬取与分析
  • 短剧出海AI工具推荐:翻译配音一站搞定
  • C语言字符串与指针核心函数手写实现与底层原理剖析
  • 深入解析Linux system()调用:从原理到安全实践
  • 汽车电子高效模型测试驱动开发:从需求到合规的零缺陷实践
  • 树莓派CM5工业应用实战:从核心模块到边缘AI系统构建
  • Barlow字体终极指南:用54种样式打造专业设计
  • KMS智能激活终极指南:一键永久激活Windows和Office的完整教程
  • 基于模型的测试驱动开发:实现功能安全与ASPICE合规的高效实践
  • 通过用量看板与成本管理功能精细化控制AI支出
  • 大麦网自动化抢票脚本:高效抢票解决方案指南
  • 外包项目的知识产权归属:甲方和乙方都该知道的底线
  • SpringBoot核心原理与实践:从配置地狱到约定大于配置的救赎