SQL内连接到左连接表

时间:2015-02-18 17:38:52

标签: 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

3 个答案:

答案 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
;

在这种情况下,首先加入表格tablebtablec,然后将其加入的结果外部加入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实现之外,什么都不会实际执行此操作。但是,结果将如下所示。

  1. 构造from子句中指定的所有表的笛卡尔积。这是您的候选结果集。
  2. 应用连接条件以消除候选结果集中的行。
  3. 应用where子句中指定的条件以进一步缩小结果集。

    注意:第2步和第3步中的区别可以更改结果集,具体取决于特定测试是放在where子句还是join条件中。这不是内连接的问题,但是对于外连接,测试的位置可能会实质性地改变结果。不要问我怎么知道这个。

  4. 应用group by子句中指定的条件(如果有)将结果集划分为组。

  5. 对于每个组,计算指定的任何聚合函数的值。

  6. 将每个组折叠为一个由其键值(来自group by子句)及其聚合函数值组成的行。

  7. 通过应用having子句中指定的条件(如果有),进一步提取结果集。

  8. 此时,您拥有最终结果集。根据{{​​1}}子句中指定的条件对其进行排序。