加入两个不匹配行数的表

时间:2013-02-21 21:26:28

标签: sql sql-server join

我有两张桌子:

Old_table(OT)

 Record_id |  Name  |  Sequence_num
------------------------------------
    78     | Austin |  0
    78     | Mike   |  1
    78     | Joe    |  2

New_table(NT)

 Record_id |  Name  |  Sequence_num
------------------------------------
    78     | Mike   |  0
    78     | Joe    |  1
    78     | Austin |  2
    78     | Fred   |  3
    78     | Ben    |  4

我正在寻找的输出表如下所示:

 Record_id |  OT_Name  |  NT_Name  |  Sequence_num
---------------------------------------------------
    78     |  Austin   |  Mike     |  0
    78     |  Mike     |  Joe      |  1
    78     |  Joe      |  Austin   |  2
    78     |  NULL     |  Fred     |  3
    78     |  NULL     |  Ben      |  4

问题是我不确定每个表中有多少行。 OT可以有10行,NT可以有3行,或NT可以有超过OT,或者它们可以有相同的数字。任何在相对表中没有匹配的Sequence_num的行都需要在相应的列中具有NULL值。如果没有为这种情况为每个表创建一个函数,select语句怎么能实现呢?我无法为我的生活提出解决方案。

编辑:

使用MS Sql Sever 2008

Management Studio 10.0.1600.22

2 个答案:

答案 0 :(得分:3)

如果您使用的是支持FULL OUTER JOIN语法的数据库,则可以使用:

select 
  coalesce(ot.record_id, nt.record_id) record_id,
  ot.name OT_Name,
  nt.name NT_name,
  coalesce(ot.sequence_num, nt.sequence_num) Sequence_num
from old_table ot
full outer join new_table nt
  on ot.record_id = nt.record_id
  and ot.sequence_num =  nt.sequence_num

请参阅SQL Fiddle with Demo

答案 1 :(得分:2)

以下内容适用于任何数据库。它不依赖于full outer join

select record_id,
       MAX(case when which = 'ot' then name end) as ot_name,
       MAX(case when which = 'nt' then name end) as nt_name,
       sequence_num
from ((select record_id, name, sequence_num, 'ot' as which
       from ot
      ) union all
      (select record_id, name, sequence_num, 'nt' as which
       from nt
      )
     ) t
group by record_id, sequence_num
相关问题