#测试建表语句如下:
CREATE TABLE `user` (
`id` int(11) NOT NULL,
`uid` int(11) NOT NULL,
`value` bigint(20) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
CREATE TABLE `order` (
`oid` int(11) NOT NULL,
`name` varchar(25) DEFAULT NULL,
PRIMARY KEY (`oid`)
)
insert into user(id,uid,value) values(1,1,1000);
insert into user(id,uid,value) values(2,2,2000);
insert into user(id,uid,value) values(3,3,3000);
insert into `order`(oid,name) values(1,'张三');
insert into `order`(oid,name) values(2,'李四');
insert into `order`(oid,name) values(3,'赵五');
题目:
#----------------------------------------------------#
有两张表:
#----------------------------------------------------#
user:
id uid value
1 1 1000
2 2 2000
3 3 3000
order:
oid name
1 张三
2 李四
3 赵五
#----------------------------------------------------#
问以下查询结果是什么?
#----------------------------------------------------#
select uid,value,name
from `user` u
left join `order` o
on u.uid = o.oid and o.name='赵五'
----------------------------------------------------
结果:
'''
1 1000 [NULL]
2 2000 [NULL]
3 3000 赵五
'''
----------------------------------------------------
select uid,value,name from `user` u left join `order` o on u.uid = o.oid where name ='赵五'
----------------------------------------------------
结果:
'''
3 3000 赵五
'''
为什么会结果不同?
原因:
数据库在通过连接两张或多张表来返回记录时,都会生成一张中间的临时表,然后再将这张临时表返回给用户。
在使用left jion时,on和where条件的区别如下:
1、 on条件是在生成临时表时使用的条件,它不管on中的条件是否为真,都会返回左边表中的记录。
2、where条件是在临时表生成好后,再对临时表进行过滤的条件。这时已经没有left join的含义(必须返回左边表的记录)了,条件不为真的就全部过滤掉。
假设有两张表:
表1:tab1
表2: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的过程:
第二条SQL的过程:
其实以上结果的关键原因就是left join,right join,full join的特殊性,不管on上的条件是否为真都会返回left或right表中的记录,full则具有left和right的特性的并集。 而inner jion没这个特殊性,则条件放在on中和where中,返回的结果集是相同的。
(转自:https://blog.csdn.net/wqc19920906/article/details/79785424)