我想要使用左外连接将两个表连接在一起。但是,即使我的左表只包含唯一值,右表也不止一次地满足CONDITION,因此会在结果集中添加额外的行。
复制问题的代码:
declare @tb1 table (c1 int) declare @tb2 table (c2 int) INSERT INTO @tb1 VALUES (1) INSERT INTO @tb1 VALUES (2) INSERT INTO @tb1 VALUES (3) INSERT INTO @tb1 VALUES (4) INSERT INTO @tb2 VALUES (3) INSERT INTO @tb2 VALUES (4) INSERT INTO @tb2 VALUES (5) INSERT INTO @tb2 VALUES (6) select * from @tb1 left outer join @tb2 ON c1 = c2 INSERT INTO @tb2 VALUES (3) INSERT INTO @tb2 VALUES (4) INSERT INTO @tb2 VALUES (5) INSERT INTO @tb2 VALUES (6) select * from @tb1 left outer join @tb2 ON c1 = c2
正如您所看到的,第一个SELECT返回4行,其中第二个SELECT 6,尽管左表保持不变。
如何对左表保持严格,只使用右表来补充左表中的行?
HELP!
RESULTS: c1 c2 ----------- ----------- 1 NULL 2 NULL 3 3 4 4 [DUPLICATE @tb2 records] c1 c2 ----------- ----------- 1 NULL 2 NULL 3 3 3 3 4 4 4 4
答案 0 :(得分:14)
很抱歉,但你的想法有所偏差。
以这种方式思考:如果你只想从tb2为tb1中的每一行提供一行,服务器应选择哪一行?事实上,从连接的定义来看,右侧表中与左侧行匹配的每一行都是匹配的,必须包含在内。
在连接之前,您必须确保tbl2具有c2的不同值。如果您的SQL变体支持DISTINCT [column](并非全部都支持),Murph的建议可能会这样做。
答案 1 :(得分:4)
尝试使用
select DISTINCT * from @tb1 left outer join @tb2 ON c1 = c2
答案 2 :(得分:4)
如果您想在左侧只保留一行,则需要为左侧的每个唯一值确定要在右侧显示的内容。例如,如果要显示计数,则可以执行以下操作:
select b1.c1, x.c from @tb1 b1
left outer join
(
select c2, count(*) as c
from @tb2
group by c2
) as x
ON b1.c1 = x.c2
或者如果你只是想要从c2中出现一个值:
select b1.c1, x.c2 from @tb1 b1
left outer join
(
select c2
from @tb2
group by c2
) as x
ON b1.c1 = x.c2
答案 3 :(得分:4)
嗯,由于右侧表中有重复记录(或至少重复的标识符),查询正在按照预期进行操作。
要获得您想要的效果:
SELECT * FROM @tb1 LEFT OUTER JOIN (SELECT DISTINCT c2 FROM @tb2) t2 ON @tb1.c1 = t2.c2
如果这还不够,您需要更详细地解释一下这个要求。
答案 4 :(得分:3)
从@ tb1中选择distinct *从左外连接@ tb2 ON c1 = c2