JOIN 关联表中 ON、WHERE 后面跟条件的区别
阅读原文时间:2023年08月25日阅读:1

SQL中join连接查询时条件放在on后与where后的区别

数据库在通过连接两张或多张表来返回记录时,都会生成一张中间的临时表,然后再将这张临时表返回给用户。

在使用left jion时,on和where条件的区别如下:

1、 on条件是在生成临时表时使用的条件,它不管on中的条件是否为真,都会返回左边表中的记录。

2、where条件是在临时表生成好后,再对临时表进行过滤的条件。这时已经没有left join的含义(必须返回左边表的记录)了,条件不为真的就全部过滤掉。

表1:

表2:

sql语句1:

SELECT
t1.ip,
t1.addr,
t2.`port`,
t2.first_time,
t2.last_time
 FROM
dws_apl_dau t1
LEFT JOIN dws_apl_hsu t2
on t1.ip=t2.ip

返回结果为表1能所有数据以及表2关联上的数据:

SELECT
t1.ip,
t1.addr,
t2.`port`,
t2.first_time,
t2.last_time
 FROM
dws_apl_dau t1
LEFT JOIN dws_apl_hsu t2
on t1.ip=t2.port

结论:当使用left join时,无论on的条件是否满足,都会返回左表的所有记录,对于满足的条件的记录,两个表对应的记录会连接起来,对于不满足条件的记录,那右表字段全部是null

sql语句2: 当在on条件后加上and关键词时:

SELECT
t1.ip,
t1.addr,
t2.`port`,
t2.first_time,
t2.last_time
 FROM
dws_apl_dau t1
LEFT JOIN dws_apl_hsu t2
on t1.ip=t2.ip
 AND t2.`port` = '1233'

解释:on后加了and就是关联满足条件的表2的数据,但是结果数据不做过滤,显示全部表1数据,下面例2一样的效果

例2:

SELECT
t1.ip,
t1.addr,
t2.`port`,
t2.first_time,
t2.last_time
 FROM
dws_apl_dau t1
LEFT JOIN dws_apl_hsu t2
on t1.ip=t2.ip
 AND t1.`addr` = 'bj'

SELECT
t1.ip,
t1.addr,
t2.`port`,
t2.first_time,
t2.last_time
 FROM
dws_apl_dau t1
LEFT JOIN dws_apl_hsu t2
on t1.ip=t2.ip
 AND t1.`addr` = 'bj' AND t2.`port` = 1111

当没有满足and条件,则返回空数据

结论:left join 接 on 在接 and  指定关联后表满足and条件的数据,有几条满足就返回表2几条数据,都不满足就返回表1全部数据和空的关联字段,不做过滤!!

sql语句3:

SELECT
t1.ip,
t1.addr,
t2.`port`,
t2.first_time,
t2.last_time
 FROM
dws_apl_dau t1
LEFT JOIN dws_apl_hsu t2
on t1.ip=t2.ip
where t1.`addr` = 'bj'

SELECT
t1.ip,
t1.addr,
t2.`port`,
t2.first_time,
t2.last_time
 FROM
dws_apl_dau t1
LEFT JOIN dws_apl_hsu t2
on t1.ip=t2.ip
where t1.`addr` = 'bj'
and t2.`port`=1233

on是在生成连接表的起作用的,where是生成连接表之后对连接表再进行过滤,相当于where之前做了子查询,返回满足where条件的数据。

以上结果的关键原因就是left join,right join,full join的特殊性,不管on上的条件是否为真都会返回left或right表中的记录,full则具有left和right的特性的并集。 而inner jion没这个特殊性,则条件放在on中和where中,返回的结果集是相同的。