多表关联中INNER JOIN与LEFT JOIN在次级表的差异咨询
多表JOIN类型导致结果差异的原因解析
问题核心在于INNER JOIN的过滤逻辑会作用于前面LEFT JOIN产生的结果集,并非你认为的“只影响TABLE2和TABLE3的关联”,具体拆解两个示例的执行过程:
示例1(两次LEFT JOIN)的执行逻辑
- 首先执行
TABLE1 LEFT JOIN TABLE2:返回TABLE1的全部5条数据,其中STEVE、EMILY对应的TABLE2.ID为NULL(因为TABLE2中无这两人的记录) - 接着执行
LEFT JOIN TABLE3:LEFT JOIN会保留左表(即第一步的结果集)的所有行,哪怕TABLE2.ID是NULL,所以这两条NULL行也会被保留,对应的HOBBIES字段为NULL,最终返回所有5个NAME。
示例2(LEFT JOIN后接INNER JOIN)的执行逻辑
- 第一步和示例1一致,得到包含5条数据的结果集,其中STEVE、EMILY的
TABLE2.ID为NULL - 然后执行
INNER JOIN TABLE3:INNER JOIN要求连接条件两边必须匹配,但SQL中NULL和任何值都不相等(包括另一个NULL),所以这两条TABLE2.ID为NULL的行无法与TABLE3的任何记录匹配,直接被过滤,最终仅返回有HOBBIES的3个NAME。
保留所有NAME的正确写法
如果想保留TABLE1的全部NAME,同时关联TABLE3的HOBBIES,要么沿用示例1的两次LEFT JOIN,要么将TABLE2和TABLE3的关联打包为子查询后再与TABLE1做LEFT JOIN:
SELECT NAME, HOBBIES FROM TABLE1 LEFT JOIN ( SELECT TABLE2.NAME, TABLE3.HOBBIES FROM TABLE2 INNER JOIN TABLE3 ON TABLE2.ID = TABLE3.ID ) AS T2_T3 ON TABLE1.NAME = T2_T3.NAME
这个写法先让TABLE2和TABLE3做INNER JOIN得到有HOBBIES的NAME集合,再通过LEFT JOIN关联TABLE1,既能保留所有TABLE1的NAME,无HOBBIES的记录对应字段会显示NULL。
内容的提问来源于stack exchange,提问作者JJBB
相关产品推荐
相关产品推荐

