所以这可能是关于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
答案 0 :(得分:14)
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
;
在这种情况下,首先加入表格tableb
和tablec
,然后将其加入的结果外部加入tablea
。
但是,最终结果集与@simon at rcl's solution相同。
答案 1 :(得分:4)
在这种情况下,如果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
即使没有匹配的tableb行,也会在没有tablec行的情况下为每个tablea和tableb提供每个tablea行。
答案 2 :(得分:2)
就SQL而言,连接顺序是无关紧要的(除了连接标准所暗示的任何顺序)。像
这样的东西select *
from t1
left join t2 on t2.t1_id = t1.id
join t3 on t3.id = t1.t3_id
与
完全相同select *
from t1
join t3 on t3.id = t1.t3_id
left join t2 on t2.t1_id = t1.id
以下是select
查询的工作原理的概念模型。当然,应该注意的是,由于步骤#1隐含的性能影响,除了最简单的SQL实现之外,什么都不会实际执行此操作。但是,结果将如下所示。
from
子句中指定的所有表的笛卡尔积。这是您的候选结果集。应用where
子句中指定的条件以进一步缩小结果集。
注意:第2步和第3步中的区别可以更改结果集,具体取决于特定测试是放在where
子句还是join
条件中。这不是内连接的问题,但是对于外连接,测试的位置可能会实质性地改变结果。不要问我怎么知道这个。
应用group by
子句中指定的条件(如果有)将结果集划分为组。
对于每个组,计算指定的任何聚合函数的值。
将每个组折叠为一个由其键值(来自group by
子句)及其聚合函数值组成的行。
通过应用having
子句中指定的条件(如果有),进一步提取结果集。
此时,您拥有最终结果集。根据{{1}}子句中指定的条件对其进行排序。