关于SQL JOIN执行顺序的疑问:三表连接查询结果确认
关于SQL JOIN执行顺序的困惑解析
首先得给你明确一点:你对原查询逻辑执行顺序的理解是完全正确的,但资料里“连接顺序不影响结果”的说法是有前提的,咱们一步步拆解清楚:
1. 你的查询的逻辑语义
你写的查询:
SELECT * FROM Table_a a LEFT JOIN Table_b b ON a.id=b.id INNER JOIN table_c c ON b.id=c.id
从SQL的逻辑执行顺序来看,确实是:
- 第一步:先执行
Table_a a LEFT JOIN Table_b b ON a.id=b.id,得到一个中间结果集——包含Table_a的所有行,以及Table_b中匹配a.id的行(不匹配的Table_b列会填充为NULL)。 - 第二步:把这个中间结果集和
Table_c c做INNER JOIN,条件是b.id=c.id。这一步会过滤掉两种行:- 所有
b.id为NULL的行(因为NULL和任何值比较的结果都是UNKNOWN,INNER JOIN只保留条件为TRUE的行); b.id在Table_c中没有匹配的行。
- 所有
2. 为什么资料说“连接顺序不影响结果”?
这里的“连接顺序”指的是数据库查询优化器选择的物理执行顺序,而不是你写的逻辑顺序。你的查询恰好因为第二步的INNER JOIN过滤,最终语义等价于三个表的全内连接:
SELECT * FROM Table_a a INNER JOIN Table_b b ON a.id=b.id INNER JOIN Table_c c ON b.id=c.id
而全内连接是满足交换律和结合律的——不管优化器选择先连接哪两张表,最终结果都是一样的。这就是资料里说法的适用场景。
举个例子验证:
假设:
Table_a的id:1, 2, 3Table_b的id:2, 3Table_c的id:2
按你的逻辑顺序执行,最终结果只有id=2的行;而直接执行三个内连,结果也是一样的。优化器可以选择先连Table_b和Table_c,再连Table_a,结果完全相同。
3. 逻辑顺序真的会影响结果吗?
当然会!如果调整逻辑顺序,比如把Table_b和Table_c的内连用括号包裹,变成:
SELECT * FROM Table_a a LEFT JOIN (Table_b b INNER JOIN Table_c c ON b.id=c.id) ON a.id=b.id
这时候逻辑顺序是先内连Table_b和Table_c(得到id=2的行),再左连Table_a,最终结果会包含Table_a的所有行:id=1(b和c列全为NULL)、id=2(有b和c的数据)、id=3(b和c列全为NULL)——这和原查询的结果完全不同。
总结
- 你对原查询逻辑执行顺序的理解没有错,原查询确实是先左连再内连,结果取决于前一步的连接结果;
- 资料里的说法只适用于全内连接的场景,你的查询恰好等价于全内连接,所以物理执行顺序可以调整但结果不变;
- 当混合左连接和内连时,逻辑顺序(也就是你写JOIN的顺序/括号分组)直接决定最终结果,一定要注意。
内容的提问来源于stack exchange,提问作者raspi surya
相关产品推荐
相关产品推荐

