SQL Server: предложение динамического соединения - PullRequest
0 голосов
/ 10 октября 2018

У меня есть 2 таблицы:

Таблица A

Id extId

Таблица B

Id1 ID2 ID3 id4

Теперь я хочунаписать соединение на таблице A с таблицей B.Запрос должен сначала присоединиться к TableA.extid=TableB.Id1.Если запись не найдена, присоединение должно произойти на TableA.extid=tableB.Id2 и т. Д. Каков наилучший способ добиться этого на сервере sql?

Ответы [ 3 ]

0 голосов
/ 10 октября 2018

UNION может быть хорошим вариантом, если известно число Id1, Id2, Id3, Id4 и т. Д.

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
0 голосов
/ 10 октября 2018

Я понимаю задачу как: соединить таблицы на ID1.Если запрос не дает результата, тогда объедините таблицы в ID2.И т. Д. Если это правильно, то:

Вы можете просто объединить все идентификаторы, а затем оставить только строки, объединенные по «лучшему» идентификатору с предложением TOP:

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;

Если вы скорее имеете в виду строк (то есть, если нет совпадения для ID1 для строки TableA в TableB, затем попробуйте ID2 и т. Д.), То вы будете использовать ту же технику, но использовать оконную функцию с разделением на частивместо идентификатора:

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   |     |
0 голосов
/ 10 октября 2018

Использовать несколько 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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...