SQL 内连接到左连接 table

SQL inner joining to left joined table

所以这可能更像是一个关于 MySQL 中的连接如何工作的理论问题,但我希望得到一些指导。

假设我有三个 tables,table a、b 和 c,其中 table a 和 b 是事实 tables 和 table c 是 table b 的维度 table。如果我想 left join table b 到 table a (我想保留 table a 的所有内容,但也想匹配 table b 中的内容),我还能在内部加入 table c 到 table b 即使 table b 被左加入吗?还是我必须离开 join table c 到 table 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

在这种情况下,如果没有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 行,这也会为您提供每个 tablea 行,并且在没有 tablec 行时也为您提供每个 tablea 和 tableb。

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

但是,最终结果集与 相同。

就 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 查询如何工作的概念模型。当然,Once 应该注意,由于步骤 #1 隐含的性能影响,除了最微不足道的 SQL 实现之外,别无他法。但是,结果将与您完成以下步骤一样。

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

    注意: 在第二步和第三步中所做的区分可以更改结果集,具体取决于特定测试是放在 where 子句中还是 join 标准。这不是内部连接的问题,但对于外部连接,测试的位置可能会显着改变结果。别问我怎么知道的

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

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

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

  7. 通过应用 having 子句(如果有)中指定的标准进一步筛选结果集。

  8. 至此,您有了最终的结果集。根据 order by 子句中指定的条件对其进行排序。