代码之家  ›  专栏  ›  技术社区  ›  Theofanis Pantelides

左外部连接(提供额外的行)问题

  •  10
  • Theofanis Pantelides  · 技术社区  · 16 年前

    我有两个表,我想用左外部联接将它们联接在一起。但是,即使我的左表只包含唯一的值,右表也多次满足条件,因此会向结果集添加额外的行。

    复制问题的代码:

    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
    
    5 回复  |  直到 16 年前
        1
  •  13
  •   Tor Haugen    16 年前

    对不起,但是你的想法有偏差。

    这样想:如果您只想从tb2中为tb1中的每一行选择一行,那么服务器应该选择哪一行?事实上,从联接的定义来看,与左侧行匹配的右侧表中的每一行都是匹配的,必须包括在内。

    在连接之前,必须确保tbl2具有不同的c2值。如果您的SQL变体支持不同的[列],Murph的建议可能会做到这一点(并非全部做到)。

        2
  •  4
  •   Adriaan Stander    16 年前

    试用使用

    select DISTINCT * from @tb1 left outer join @tb2 ON c1 = c2
    
        3
  •  4
  •   Murph    16 年前

    嗯,查询正在做它应该做的事情,因为在右手边的表中有重复的记录(或者至少有重复的标识符)。

    为了达到你想要的效果,比如:

    SELECT * FROM @tb1 LEFT OUTER JOIN (SELECT DISTINCT c2 FROM @tb2) t2 ON @tb1.c1 = t2.c2
    

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

        4
  •  3
  •   Gennady Shumakher    16 年前

    选择distinct*from@tb1 left outer join@tb2 on c1=c2

        5
  •  3
  •   davek    16 年前

    如果只想在左侧保留一行,则需要为左侧的每个唯一值决定要在右侧显示的内容。例如,如果要显示计数,可以执行以下操作:

    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