SQL 内连接到左连接表
Posted
技术标签:
【中文标题】SQL 内连接到左连接表【英文标题】:SQL inner joining to left joined table 【发布时间】:2015-02-18 17:38:51 【问题描述】:所以这可能更像是一个关于 mysql 中的连接如何工作的理论问题,但我希望得到一些指导。
假设我有三个表,表 a、b 和 c,其中表 a 和 b 是事实表,表 c 是表 b 的维度表。如果我想将表 b 左连接到表 a(我想保留表 a 的所有内容,但也想匹配表 b 中的内容),即使表 b 左连接,我还能将表 c 内连接到表 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
【问题讨论】:
那个连接会杀死左连接。如果你把 b 放在一个 where is 也会杀死左边。 【参考方案1】: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 相同。
【讨论】:
【参考方案2】:在这种情况下,如果 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。
【讨论】:
【参考方案3】:就 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 实现之外,没有什么会真正做到这一点。但是,结果就像您完成了以下步骤一样。
-
构造
from
子句中指定的所有表的笛卡尔积。这是您的候选结果集。
应用连接条件从候选结果集中消除行。
应用where
子句中指定的条件来进一步缩小结果集。
注意:第二步和第三步中的区别可能会改变结果集,具体取决于特定测试是放在where
子句还是join
标准中。这不是内部连接的问题,但是对于外部连接,测试的位置可以大大改变结果。不要问我是怎么知道的。
应用group by
子句(如果有)中指定的条件将结果集划分为组。
对于每个组,计算指定的任何聚合函数的值。
将每个组折叠成一行,其中包含其键值(来自group by
子句)及其聚合函数的值。
通过应用having
子句(如果有)中指定的条件进一步筛选结果集。
此时,您已获得最终结果集。根据order by
子句中指定的标准对其进行排序。
【讨论】:
以上是关于SQL 内连接到左连接表的主要内容,如果未能解决你的问题,请参考以下文章