在两个表/查询之间连接时:
with
cte1 (id) as (
select 1 from dual),
cte2 (id) as (
select 1 from dual union all
select 1 from dual)
select
cte1.id as cte1_id,
cte2.id as cte2_id
from
cte1
left join
cte2
on cte1.id = cte2.id
CTE1_ID CTE2_ID
1 1
1 1
不出所料,该联接会传播出额外的行。联接左侧的查询只有一行。但是由于连接,结果集有两行。
我怀疑"传播"这个词不太适合描述这种情况。
什么是恰当的术语?
例如,当与刚接触SQL的人交谈时,我经常说:"小心连接。看起来你不小心传播了额外的行,因为连接是1:many。">
在这个例子中,您没有传播行(至少在我看来是这样(。表中联接右侧有两行,结果中有两行。
然而,如果你有这个:
WITH cte AS
(
SELECT 1 AS id FROM dual
UNION ALL
SELECT 1 FROM dual
)
SELECT x.id, y.id
FROM cte x
INNER JOIN cte y ON x.id = y.id;
您将从2行开始,查询将返回4行,因为联接是部分联接。对我来说,这是在传播数据。
当联接一侧的每一行与另一侧的每行联接时,您要查找的术语是"联接";笛卡尔乘积";,这是在SQL中使用";交叉连接";或者,在联接不是唯一的但部分受限的情况下,可以使用";偏笛卡尔积";(尽管我不推荐(或更常见的";部分交叉连接";。我认为后者更容易受到SQL开发人员的赞赏。
在任何一种情况下,有时两者都是合适的,但很多时候它们是联接子句中错误的结果。
什么是恰当的术语?
"笛卡尔乘积";可能是你可以使用的一个术语。
即";小心那个接头。看起来您不小心返回了两个表的笛卡尔乘积">
CROSS JOIN
将返回两个联接表的笛卡尔乘积;它也被称为";笛卡尔连接";。
INNER JOIN
将返回通过两个表的列之间的某种关系(联接条件(过滤的两个联接表的笛卡尔乘积;它也被称为";Equi Join";。
OUTER JOIN
类似于INNER JOIN
,但也将在联接条件的一侧(对于LEFT
或RIGHT
联接(或两侧(对于FULL
联接(返回不匹配的行。
为什么LEFT JOIN
和INNER JOIN
也会这么做!
不,它不会传播,在cte2中有2个id,其中1是UNION ALL
实际调用的,所以当您使用相同的id联接两个表时,您将收到2行作为联接结果集。
Left Join还将左表和troes中的所有行按id进行连接,如果没有找到任何对应的行,则将具有右表列的行添加为NULL
。
所以没有奇迹也没有奇迹,简单的SQL