我有2张桌子:
TableA
Id extId
TableB
Id1 ID2 ID3 id4
现在我想用tableB在tableA上编写一个联接。
查询应首先在TableA.extid=TableB.Id1
上加入。
如果未找到任何记录,则应在TableA.extid=tableB.Id2
等上进行加入。
在sql server中实现此目标的最佳方法是什么?
答案 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