SQL Server:动态联接子句

时间:2018-10-10 11:49:28

标签: sql sql-server join

我有2张桌子:

TableA

Id extId

TableB

Id1 ID2 ID3 id4

现在我想用tableB在tableA上编写一个联接。 查询应首先在TableA.extid=TableB.Id1上加入。 如果未找到任何记录,则应在TableA.extid=tableB.Id2等上进行加入。 在sql server中实现此目标的最佳方法是什么?

3 个答案:

答案 0 :(得分:3)

使用多个left join

select coalese(a1.id, a2.id, a3.id, a4.id) as a_id, b.*
from b left join
     a a1
     on b.id1 = a1.extid left join
     a a2
     on b.id2 = a2.extid and a1.extid is null left join
     a a3
     on b.id3 = a3.extid and a2.extid is null left join
     a a4
     on b.id4 = a4.extid and a3.extid is null 
where a1.extid is not null or a2.extid is not null or a3.extid ia not null or a4.extid is not null;

答案 1 :(得分:1)

我将任务理解为:连接ID1上的表。如果查询没有结果,请联接ID2上的表。等等。如果这是正确的,那么:

您可以简单地连接所有ID,然后使用TOP子句仅保留连接在“最佳” ID上的行:

select top(1) with ties *
from tablea a
join tableb b on a.extid in (b.id1, b.id2, b.id3, b.id4)
order by
  case when a.extid = b.id1 then 1
       when a.extid = b.id2 then 2
       when a.extid = b.id3 then 3
       when a.extid = b.id4 then 4
  end;

如果您想说的是(即,如果TableB中的TableA行的ID1不匹配,则尝试ID2,依此类推),那么您将使用相同的技术,但是使用按ID划分的窗口函数:

select top(1) with ties *
from tablea a
join tableb b on a.extid in (b.id1, b.id2, b.id3, b.id4)
order by 
  row_number() over (
    partition by a.id
    order by 
      case when a.extid = b.id1 then 1
           when a.extid = b.id2 then 2
           when a.extid = b.id3 then 3
           when a.extid = b.id4 then 4
      end);

样本数据:

TableA

ID   | EXTID
-----+------
100  | 1
200  | 2
300  | 3
400  | 4

TableB

ID1 | ID2 | ID3 | ID4
----+-----+-----+----
2   | 3   |     |
2   | 4   |     |
3   | 4   |     |
3   | 2   | 4   | 1

Result for query #1 (all matches on ID1):

ID  | EXTID | ID1 | ID2 | ID3 | ID4
----+-------+-----+-----+-----+----
200 | 2     | 2   | 3   |     |
200 | 2     | 2   | 4   |     |
300 | 3     | 3   | 4   |     |
300 | 3     | 3   | 2   | 4   | 1

Result for query #2 (first matching ID):

ID  | EXTID | ID1 | ID2 | ID3 | ID4
----+-------+-----+-----+-----+----
100 | 1     | 3   | 2   | 4   | 1
200 | 2     | 2   | 3   |     |
200 | 2     | 2   | 4   |     |
300 | 3     | 3   | 4   |     |
300 | 3     | 3   | 2   | 4   | 1
400 | 4     | 2   | 4   |     |
400 | 4     | 3   | 4   |     |

答案 2 :(得分:0)

如果已知Id1,Id2,Id3,Id4等数目,UNION可能是一个不错的选择。

SELECT ta.Id,
ta.extId,
tb.Id1 AS JoinedID
FROM TableA ta
INNER JOIN TableB tb ON ta.extId = tb.Id1

UNION

SELECT ta.Id,
ta.extId,
tb.Id2 AS JoinedID
FROM TableA ta
INNER JOIN TableB tb ON ta.extId = tb.Id2

UNION

SELECT ta.Id,
ta.extId,
tb.Id3 AS JoinedID
FROM TableA ta
INNER JOIN TableB tb ON ta.extId = tb.Id3

UNION

SELECT ta.Id,
ta.extId,
tb.Id4 AS JoinedID
FROM TableA ta
INNER JOIN TableB tb ON ta.extId = tb.Id4