如何连接两个没有唯一ID的表

时间:2017-06-20 11:30:49

标签: sql-server tsql join unique

我试图将表1连接到表2

Table1          Table2  
ID  Data        ID  Data2
1   r           1   q
2   t           1   a
3   z           2   x
1   u           3   c

在我离开加入这两张桌子后,我想得到这样的东西

  Table1+2      
ID  Data    Data2
1   r        a
2   t        x
3   z        c
1   u        q

而不是

  Table1+2      
ID  Data    Data2
1   r        q
2   t        x
3   z        c
1   u        q

我的问题是:有没有可能告诉表2,如果你已经使用了表1的东西,不要使用它并给我下一个值。我必须使它成为即时T-SQL或新列,我可以列出如果该ID存在,那么写2如果不是1(数字数据)。我怎么解决这个问题? 提前你。

2 个答案:

答案 0 :(得分:2)

Since there's no uniqueness in the ID on both tables, lets add some uniqueness to it.
So it can be used to join on.
The window function ROW_NUMBER can be used for that.

An example solution that gives the expected result:

DECLARE @TestTable1 TABLE (ID INT, Data VARCHAR(1));
DECLARE @TestTable2 TABLE (ID INT, Data VARCHAR(1));

INSERT INTO @TestTable1 VALUES (1,'r'),(2,'t'),(3,'z'),(1,'u');         
INSERT INTO @TestTable2 VALUES (1,'q'),(1,'a'),(2,'x'),(3,'c');

select 
 t1.ID, t1.Data,
 t2.Data as Data2
from (
  select ID, Data, 
  row_number() over (partition by ID order by Data) as rn
  from @TestTable1
) t1
left join (
  select ID, Data, 
  row_number() over (partition by ID order by Data) as rn
  from @TestTable2
) t2 on t1.ID = t2.ID and t1.rn = t2.rn;

Note: Because of the LEFT JOIN, this does assume the amount of same ID's in table2 are equal or lower can those on table1. But you can change that to a FULL JOIN if that's not the case.

Returns :

ID  Data Data2
1   r    a
1   u    q
2   t    x
3   z    c

To get the other result could have been achieved in different ways.
This is actually a more common situation.
Where one wants all from Table 1, but only get one value from Table 2 for each record of Table 1.

1) A top 1 with ties in combination with a order by rownumber()

select top 1 with ties 
 t1.ID, t1.Data,
 t2.Data as Data2
from @TestTable1 t1
left join @TestTable2 t2 on t1.ID = t2.ID
order by row_number() over (partition by t1.ID, t1.Data order by t2.Data desc);

The top 1 with ties will only show those where the row_number() = 1

2) Using the row_number in a subquery:

select ID, Data, Data2
from (
    select 
     t1.ID, t1.Data,
     t2.Data as Data2,
     row_number() over (partition by t1.ID, t1.Data order by t2.Data desc) as rn
    from @TestTable1 t1
    left join @TestTable2 t2 on t1.ID = t2.ID
) q
where rn = 1;

3) just a simple group by and a max :

select t1.ID, t1.Data, max(t2.Data) as Data2
from @TestTable1 t1
left join @TestTable2 t2 on t1.ID = t2.ID
group by t1.ID, t1.Data
order by 1,2;

All 3 give the same result:

ID Data Data2
1  r    q
1  u    q
2  t    x
3  z    c

答案 1 :(得分:0)

使用ROW_NUMBER

DECLARE @Table1 TABLE (ID INT, DATA VARCHAR(10))
DECLARE @Table2 TABLE (ID INT, DATA VARCHAR(10))

INSERT INTO @Table1
VALUES
(1,   'r'),        
(2,   't'),        
(3,   'z'),        
(1,   'u')         

INSERT INTO @Table2
VALUES
(1,   'q'),
(1,   'a'),
(2,   'x'),
(3,   'c')   

SELECT
    A.*,
    B.DATA
FROM
    (SELECT *, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY(SELECT NULL)) RowId FROM @Table1) A INNER JOIN 
    (SELECT *, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY(SELECT NULL)) RowId FROM @Table2) B ON A.ID = B.ID AND
                                                                                                  A.RowId = B.RowId