left join 后用 on 还是 where?
昨天写 SQL Server 数据库上写 SQL 语句时,我原本想通过执行A left join B on ... and ...的操作,将查询结果中的两条记录合并成一条,奈何发现结果中依然有两条记录。
回顾了一下语法知识,意识到join on ... and ...的语句并不会对结果集的记录条数进行过滤。它的主要作用是,根据and后面指定的条件来决定是否显示B表的记录。而A表的记录则会无条件地显示出来。
不论and后面跟的是A.id=1还是B.id=1这样的条件,查询结果都会显示A表中的所有记录。同时,如果B表中存在与A表中id为1的记录相匹配的数据,或者B表中存在id为1的记录,这些信息也会被关联并显示出来。
运行sql :
select * from student s left join class c on s.classId=c.id order by s.id
运行sql :
select * from student s left join class c on s.classId=c.id and s.name="张三" order by s.id
运行sql :
select * from student s left join class c on s.classId=c.id and c.name="三年级三班" order by s.id
数据库通过连接多张表来返回记录的过程中,会首先生成一个中间的临时表。这个临时表是连接操作的核心,并且最终会基于这个临时表向用户展示结果。
当使用`left join`时,`on`条件的作用是在构建这个临时表时,用于确定如何连接左表和右表。无论`on`条件是否满足,左表中的所有记录都会被包含在生成的临时表中。
与之不同,`where`条件是在临时表已经构建完成之后,对临时表内容进行筛选的条件。这时,`left join`的语义(即必须返回左表的所有记录)已经不再适用。`where`条件会过滤掉不满足条件的记录,仅保留符合条件的记录作为最终的查询结果。
假设有两张表:
表1:tab2
两条SQL:1、
select * form tab1 left join tab2 on (tab1.size = tab2.size) where tab2.name=’AAA’
2、
select * form tab1 left join tab2 on (tab1.size = tab2.size and tab2.name=’AAA’)
第一条SQL的过程:
1、中间表on条件:
tab1.size = tab2.size
2、再对中间表过滤where 条件:
tab2.name=’AAA’
第二条SQL的过程:
1、中间表on条件
tab1.size = tab2.size and tab2.name=’AAA’
条件不为真也会返回左表中的记录
实际上,上述结果的关键所在正是源于left join、right join以及full join的特点。在这些连接操作中,不论on条件是否成立,都会返回left或right表中的记录。而full join则结合了left和right的特性,返回的是两者的并集。
然而,对于inner join而言,它并不具备这样的特性。因此,在inner join中,无论是将条件放在on中还是where中,最终得到的结果集都是相同的。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
2022-01-10 MySQL调优篇 | 逻辑架构解读(1)