SQL Server在主表中连接两个没有重复的表

时间:2016-11-09 10:53:31

标签: sql sql-server join

我想要连接两个表,以便返回所有外部行,并且不重复主表的行。例如:

T1  

    pk  code  value
    1   One    100
    2   Two    200

T2  

    fk   value  
    1     10  
    1     15  
    1     30  
    2     25  

我希望T2的所有记录都没有重复的T1记录,所以结果集我想看起来像这样:

 T2.fk   T1.code  T1.value T2.value  
    1      One      100       10  
    1      NULL     NULL      15  
    1      NULL     NULL      30  
    2      Two      200       25  

是否有用于实现该目的的SQL Server连接方法?

3 个答案:

答案 0 :(得分:3)

您需要在T2中对行进行排名并执行left join,包括排名作为加入条件:

with cte as(select *, row_number() over(partition by fk order by value) as rn from T2)

select c.fk, t.code, t.value, c.value 
from cte c
left join T1 t on c.fk = t.pk and c.rn = 1

以下是完整示例:

DECLARE @t1 TABLE
    (
      pk INT ,
      code VARCHAR(MAX) ,
      value INT
    )
INSERT  INTO @t1
VALUES  ( 1, 'One', 100 ),
        ( 2, 'Two', 200 )

DECLARE @t2 TABLE ( fk INT, value INT )
INSERT  INTO @t2
VALUES  ( 1, 10 ),
        ( 1, 15 ),
        ( 1, 30 ),
        ( 2, 25 );
WITH    cte
          AS ( SELECT   * ,
                        ROW_NUMBER() OVER ( PARTITION BY fk ORDER BY value ) AS rn
               FROM     @t2
             )
    SELECT  c.fk ,
            t.code ,
            t.value ,
            c.value
    FROM    cte c
            LEFT JOIN @t1 t ON c.fk = t.pk
                               AND c.rn = 1

答案 1 :(得分:0)

试试这个:

select T2.fk, 
CASE
    WHEN (SELECT COUNT(*) FROM t2 tother WHERE tother.fk = t2.fk
    AND tother.value > t2.value) > 0 THEN NULL ELSE t1.code
END,
CASE
    WHEN (SELECT COUNT(*) FROM t2 tother WHERE tother.fk = t2.fk
    AND tother.value > t2.value) > 0 THEN NULL ELSE t1.value
END,T2.value  
from t2
join t1
on t2.fk = t1.pk

答案 2 :(得分:0)

    DECLARE @t1 TABLE (pk int,code varchar(10),value int)
    DECLARE @t2 TABLE (fk int,value int)

    INSERT INTO @t1
    SELECT 1,'one',100
    UNION
    SELECT 2,'two',200

    INSERT INTO @t2
    SELECT 1,10
    UNION SELECT 1,15 UNION SELECT 1,30 UNION SELECT 2,25


;WITH cte AS(
SELECT t2.fk,t2.value t2val,t1.pk,t1.code,t1.value t1val,ROW_NUMBER() OVER(PARTITION BY fk ORDER BY fk) rno FROM @t2 t2 LEFT JOIN @t1 t1 on t2.fk=t1.pk)
SELECT fk,code=(CASE WHEN rno=1 THEN code ELSE null END),t1val=(CASE WHEN rno=1 THEN t1val ELSE NULL END),t2val FROM cte

输出

fk  code    t1val   t2val
1   one     100      10
1   NULL    NULL     15
1   NULL    NULL     30
2   two     200      25