(My)SQL 如何评估链式 LEFT/INNER JOIN?
Posted
技术标签:
【中文标题】(My)SQL 如何评估链式 LEFT/INNER JOIN?【英文标题】:How does (My)SQL evaluate chained LEFT/INNER JOINs? 【发布时间】:2013-12-15 20:30:20 【问题描述】:我们有 3 个表格:
T1: T2: T3:
id | t3_id id | name id | t2_id
---------- --------- ----------
1 | 2 1 | abc 1 | 1
2 | NULL 2 | 123 2 | 1
3 | 1 3 | ab1 3 | 3
4 | 4 4 | 32b 4 | 2
现在我们测试了以下 JOIN:
1.:
SELECT
*
FROM T1
INNER JOIN T3 ON T1.t3_id = T3.id
INNER JOIN T2 ON T3.t2_id = T2.id
WHERE T2.name = '%'
这个案子很清楚。结果:
T1.id | T1.t3_id | T3.id | T3.t2_id | T2.id | T2.name
-----------------------------------------------------
1 | 2 | 2 | 1 | 1 | abc
3 | 1 | 1 | 1 | 1 | abc
4 | 4 | 4 | 2 | 2 | 123
2.:
SELECT
*
FROM T1
LEFT JOIN T3 ON T1.t3_id = T3.id
LEFT JOIN T2 ON T3.t2_id = T2.id
WHERE T2.name = '%'
这个也清楚:
T1.id | T1.t3_id | T3.id | T3.t2_id | T2.id | T2.name
-----------------------------------------------------
1 | 2 | 2 | 1 | 1 | abc
2 | NULL | NULL | NULL | NULL | NULL
3 | 1 | 1 | 1 | 1 | abc
4 | 4 | 4 | 2 | 2 | 123
3.:
SELECT
*
FROM T1
LEFT JOIN T3 ON T1.t3_id = T3.id
INNER JOIN T2 ON T3.t2_id = T2.id
WHERE T2.name = '%'
这个有点奇怪。结果(与第一个相同):
T1.id | T1.t3_id | T3.id | T3.t2_id | T2.id | T2.name
-----------------------------------------------------
1 | 2 | 2 | 1 | 1 | abc
3 | 1 | 1 | 1 | 1 | abc
4 | 4 | 4 | 2 | 2 | 123
我不明白 mysql 如何评估这个表达式。为什么它确实忽略了 LEFT JOIN 并且似乎更喜欢 INNER JOIN。
如果我读到这个查询,就像:
-
从 T1 获取数据
通过 LEFT JOIN 从 T2 获取数据(意味着:仅在可能的情况下,否则获取 NULL 数据)
通过 INNER JOIN 从 T3 获取数据(意思是:删除所有无法通过此 INNER JOIN 连接的 T2 数据)
但好像我必须向后阅读查询?!
有人可以向我解释一下这种情况吗?
【问题讨论】:
【参考方案1】:INNER JOIN
应用于您已有的结果(即T1 LEFT JOIN T3
),而不仅仅是T3
。
你读起来像:
(T1 LEFT JOIN (T3 INNER JOIN T2))
但它就像:
((T1 LEFT JOIN T3) INNER JOIN T2)
【讨论】:
【参考方案2】:左连接类似于“OR”,INNER JOIN 类似于“AND”。所以有这样的优先级
t1 left join (t2 inner join t3)
这与
有很大不同(t1 left join t2) inner join t2
【讨论】:
以上是关于(My)SQL 如何评估链式 LEFT/INNER JOIN?的主要内容,如果未能解决你的问题,请参考以下文章