通常,当在两个表上执行左连接时,保留左表(A)的所有行,并且仅连接右表(B)以匹配连接条件,例如, A.ID = B.ID. 这适用于小型测试数据集。
然而,当我尝试使用相当大的集合B(即,B中唯一ID的数量是A中唯一ID的数量的约100倍)来连接集合A时,结果数据集仅包括那些A的那些行。与B匹配的ID,在我的理解中 - 是正常(内部)联接。
我通过左连接集合A获得了所需的结果表,只有那些具有匹配ID的集合B的那些行与集合A,但我不明白为什么简单的左连接不会产生相同的结果。
不幸的是,我无法用测试数据复制结果。
一般情况下,左连接后是否有可能导致左表被截断?
编辑:
设置A:
ID name
X1 AB
X2 XY
X3 VT
X4 ZY
X5 YZ
X6 KJ
X7 HA
X8 BK
X9 LM
设置B:
ID Var1
X1 blue
X11 red
X3 yellow
X4 blue
X12 yellow
X6 red
X7 orange
X7 blue
X8 green
X9 green
X10 blue
这给出了截断集A:
select A.*, B.Var1 from
setA A
left join setB B
on A.ID = B.ID
where B.Var1 = 'blue';
这给了我想要的东西:
select A.*, B.Var1 from
setA A
left join (select * from setB where Var1 = 'blue') B
on A.ID = B.ID;
我现在明白where
后join
过滤了加入结果,我需要将join
和where
视为两个独立的任务(正确吗?) 。
但是,对于我(作为非专家)来说,B.Var1 = 'blue'
过滤联接结果虽然它显示B.Var1
而不仅仅是Var1
,但我可以理解更多很容易引用连接结果。 B.
建议(对我来说)以某种方式影响连接中使用的左表。
答案 0 :(得分:0)
TL / DR 使用setA A left join setB B on A.ID = B.ID and B.Var1 = 'blue'
。
保留左表(A)的所有行,并且仅连接右表(B)以匹配连接条件,例如, A.ID = B.ID"
目前尚不清楚你想说的是什么。
left join on
被定义为返回inner join on
行加上由null
扩展的不匹配的左表行。如果结果中没有A的所有行,则您在where
之后添加了inner join on
(或right join on
或left join on
)。 每当您left join on
时,请清楚记住您想要的inner join on
相关内容;是什么决定了on
。
这是否意味着[outer] join中不允许使用where子句?
那个(评论)也很奇怪,因为where
永远不会"在" a(外部或内部)连接,它总是在任何连接之后。 (您可以认为inner join
与cross join
和on
类似where
,但优先级更高。)
这给了我想要的东西:
select A.*, B.Var1 from setA A left join (select * from setB where Var1 = 'blue') B on A.ID = B.ID;
这样做,"自然"措辞:
select A.*, B.Var1 from
setA A
left join setB B
on A.ID = B.ID
and B.Var1 = 'blue';
然而,对我来说(作为非专家)似乎并不自然
inner join on
定义为返回符合(整个)cross join
条件的on
行。另一种描述这种情况的方法是,对于来自每个输入的每一行可能的一对组合行,但只有当它满足(整个)on
条件时才输出。另一种描述这种情况的方法是,对于每个输入的每一对可能的行,只有当它们满足(整个)on
条件时,它们才会组合成一个输出行。
有些人似乎使用后两种解释中的一种,但却有误解。他们认为inner join on
输出不同而不是cross join
,然后按on
进行过滤。或者他们认为join
只能是on
两个输入中涉及(无论它们的意思是什么)列的条件 - 好像每个都必须被提及以便可以合并并且可能输出。但是没有 - on
条件可以是任何东西,只是针对每个可能的输入行配对进行评估。
CROSS JOIN vs INNER JOIN:CROSS JOIN =(INNER)JOIN =逗号(",")
What is the difference between “INNER JOIN” and “OUTER JOIN”?
(要注意那里的许多其他答案中的废话和写作不好。)
其中
B.Var1 = 'blue'
会过滤联接结果,虽然它会显示B.Var1
而不只是Var1
,我可以更容易地理解它来引用联接结果。B.
建议(对我来说)以某种方式影响连接中使用的左表。
这个更加不清楚&奇怪的措辞。看起来你有误解,你需要放手。如果您试图强迫自己明确表达引用的语句,以及您希望join
与on
一起工作的方式,这可能会有所帮助。 (成为/成为专家的必要条件是不能容忍阅读,思考或写作的邋。。)
答案 1 :(得分:0)
您的查询在概念上技术上很好。你只是忘了(+)运算符。它应该是
select A.*, B.Var1 from
setA A
left join setB B
on A.ID = B.ID
where B.Var1(+) = 'blue'; -- Notice the magic (+) symbol
(+)
符号来自old style Oracle join syntax,可能会发音为“其中B.Var1,如果存在,则等于蓝色。”否则它只允许变量具有匹配值的行,这意味着它必须存在。
更现代的写作方式是:
select A.*,
B.Var1
from setA A
left join setB B on A.ID = B.ID
AND B.Var1 = 'blue';
换句话说,请将其从where
中取出,并将其作为on
条件的一部分,并将其保留为and
。