LEFT OUTER JOIN(给出额外的行)问题

The*_*des 10 sql join

我有两个表,我想使用左外连接连接在一起.但是,即使我的左表只包含唯一值,右表也不止一次地满足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,尽管左表保持不变.

如何对左表保持严格,只使用右表来补充左表中的行?

救命!

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

Tor*_*gen 14

对不起,但你的想法是扭曲的.

以这种方式思考:如果你只想从tb2为tb1中的每一行提供一行,那么服务器应该选择哪一行?事实是,从连接的定义来看,右侧表中与左侧行匹配的每一行都是匹配的,必须包含在内.

在连接之前,您必须确保tbl2具有不同的c2值.如果您的SQL变体支持DISTINCT [column](并非所有的话),Murph的建议可能会这样做.


dav*_*vek 6

如果您只想在左侧保留单行,则需要为左侧的每个唯一值决定要在右侧显示的内容。例如,如果您想显示计数,您可以这样做:

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
Run Code Online (Sandbox Code Playgroud)

或者如果您只想要 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
Run Code Online (Sandbox Code Playgroud)


Adr*_*der 5

尝试使用

select DISTINCT * from @tb1 left outer join @tb2 ON c1 = c2
Run Code Online (Sandbox Code Playgroud)

  • 这在这个简化的情况下是可行的,但我很确定实际上他的 rhs 表有更多列 - 然后不同的列将无济于事。 (2认同)

Mur*_*rph 5

嗯,查询正在执行其应该执行的操作,因为右侧表中有重复的记录(或至少有重复的标识符)。

为了达到你想要的效果:

SELECT * FROM @tb1 LEFT OUTER JOIN (SELECT DISTINCT c2 FROM @tb2) t2 ON @tb1.c1 = t2.c2
Run Code Online (Sandbox Code Playgroud)

如果这还不够,您需要更详细地解释要求。