ben*_*890 5 mysql sql left-join
所以这可能更多是关于MySQL如何工作的理论问题,但我喜欢一些指导.
假设我有三个表,表a,b和c,其中表a和b是事实表,表c是表b的维表.如果我想要将表b连接到表a(我想保留表a的所有内容,但也想要表b中的匹配内容),我是否仍然可以将表c连接到表b,即使表b仍然连接?或者我是否必须将表c连接到表b?或者这两种意图和目的是否会产生相同的结果?
select a.column, c.name
from tablea a
left join tableb b on a.id = b.id
inner join (?) tablec c on b.name_id = c.name
Run Code Online (Sandbox Code Playgroud)
And*_*y M 18
MySQL支持允许您实现所需内容的语法:
select a.column, c.name
from
tablea a
left join
tableb b
inner join tablec c on b.name_id = c.name
on a.id = b.id
;
Run Code Online (Sandbox Code Playgroud)
在这种情况下,表tableb和tablec第一个连接,然后它们的连接结果是外连接到tablea.
然而,最终结果集与rcl解决方案中的@simon相同.
在这种情况下,如果 tableb 没有 tablec 条目,则整个连接将失败,并且 tablea 行将不会被包含在内。要包含 tablsa 条目,您需要将与 tablc 的连接设为左连接:
select a.column, c.name
from tablea a
left join tableb b on a.id = b.id
left join tablec c on b.name_id = c.name
Run Code Online (Sandbox Code Playgroud)
即使没有匹配的 tableb 行,这也会获得每个 tablea 行,并且当没有 tablec 行时也会获得每个 tablea 和 tableb。
就 SQL 而言,连接顺序无关紧要(连接条件隐含的任何顺序除外)。就像是
select *
from t1
left join t2 on t2.t1_id = t1.id
join t3 on t3.id = t1.t3_id
Run Code Online (Sandbox Code Playgroud)
完全一样
select *
from t1
join t3 on t3.id = t1.t3_id
left join t2 on t2.t1_id = t1.id
Run Code Online (Sandbox Code Playgroud)
这是查询如何工作的概念模型select。当然,应该注意的是,由于步骤 #1 隐含的性能影响,除了最简单的 SQL 实现之外,没有任何其他方法实际上会执行此操作。但是,结果将与您执行以下步骤一样。
from。这是您的候选结果集。应用子句中指定的条件where进一步缩小结果集范围。
注意:第二步和第三步中的区别可能会更改结果集,具体取决于特定测试是否放置在子句where或join条件中。这不是内部联接的问题,但对于外部联接,测试的位置可能会严重改变结果。别问我怎么知道这些。
应用子句中指定的条件group by(如果有)将结果集分区。
对于每个组,计算指定的任何聚合函数的值。
将每个组折叠成一行,由其键值(来自子句group by)及其聚合函数的值组成。
通过应用子句中指定的标准(如果有)进一步筛选结果集having。
此时,您已获得最终结果集。根据order by条款中指定的标准进行订购。