Я пытаюсь сопоставить записи между тремя таблицами, две таблицы — это данные для сопоставления, третья таблица — это центральная таблица, которая указывает мне, как должны сопоставляться записи.
Пример будет понятнее, чем длинная речь:
Таблица 1
Value1 A1 B1 C1
------------------
0.1 1 b z
0.2 4 b z
1.1 5 b z
1.5 5 c y
2.5 7 c x
Таблица 2
Value2 A2 B2 C2
------------------
0.5 1 d z
0.7 4 d z
2.3 7 d z
1.7 5 e y
1.9 7 e x
Таблица 3
BL BR C
-----------
d b z
c e x
c e y
Способ увидеть это так: A представляет холдинги, C — держатели, а B — даты. Таким образом, Таблица 1 сообщает мне, какие активы есть в некоторые даты, Таблица 2 сообщает мне то же самое в некоторые другие даты, и, наконец, Таблица 3 говорит мне, как сравнивать активы, например. для держателя C = z я хочу сравнить владения между датами B = d и датой B = b (на практике таблицы 1 и 2 совпадают).
Итак, я ищу таблицу для сравнения холдингов, принимая во внимание холдинги, которые были созданы, и холдинги, которые были удалены. Я ищу что-то вроде этого:
Value1 A1 B1 C1 BR BL C A2 B2 C2 Value2
-------------------------------------------
0.1 1 b z b d z 1 d z 0.5
0.2 4 b z b d z 4 d z 0.7
1.1 5 b z b d z
b d z 7 d z 2.3
1.5 5 c y c e y 5 e y 1.7
2.5 7 c x c e x 7 e x 1.9
Таким образом, записи совпадают только в том случае, если A1 = A2, C1 = C2 и B1 = BR, B2 = BL, в противном случае он пуст с той или иной стороны.
Я надеюсь, что это ясно. Я пробовал различные подходы (левое/правое/полное соединение) без успеха. Приветствуется любая помощь!
Спасибо
РЕДАКТИРОВАТЬ Добавление примера кода. Это T-SQL.
CREATE TABLE #T1 (Value1 FLOAT, A1 INT, B1 CHAR, C1 CHAR);
CREATE TABLE #T2 (Value2 FLOAT, A2 INT, B2 CHAR, C2 CHAR);
CREATE TABLE #T3 (BR CHAR, BL CHAR, C CHAR);
INSERT INTO #T1 VALUES (0.1, 1, 'b', 'z'),
(0.2, 4, 'b', 'z'),
(1.1, 5, 'b', 'z'),
(1.5, 5, 'c', 'y'),
(2.5, 7, 'c', 'x');
INSERT INTO #T2 VALUES (0.5, 1, 'd', 'z'),
(0.7, 4, 'd', 'z'),
(2.3, 7, 'd', 'z'),
(1.7, 5, 'e', 'y'),
(1.9, 7, 'e', 'x');
INSERT INTO #T3 VALUES ('b', 'd', 'z'),
('c', 'e', 'x'),
('c', 'e', 'y');
Пример запроса, который я пробовал.
SELECT
*
FROM #T3
LEFT JOIN #T1 ON #T1.B1 = #T3.BR AND #T1.C1 = #T3.C
FULL JOIN #T2 ON #T2.B2 = #T3.BL AND #T2.C2 = #T3.C AND #T2.A2 = #T1.A1
Вот что я получаю результат. Близко, но я бы хотел, чтобы BR, BL и C никогда не были NULL, потому что после этого у меня есть некоторая логика в этих столбцах. Эти столбцы не обязательно должны быть нулевыми в последней строке, их можно сопоставить со строкой в #T3.
Вся сложность в AND #T2.A2 = #T1.A1: если такая запись существует, я хочу, чтобы она совпадала, но если нет, я бы хотел, чтобы она вел себя так, как если бы второе соединение было ЛЕВЫМ СОЕДИНЕНИЕМ на #T2.B2 = #T3.BL AND #T2.C2 = #T3.C
РЕДАКТИРОВАТЬ 2 Благодаря сообщению Marlin Pierce, вот запрос, который возвращает результат, который я ищу:
SELECT Value1 A1, B1, C1, BR, BL, C, A2, B2, C2, Value2
FROM #T3 inner join #T1 on #T1.B1 = #T3.BR AND #T1.C1 = #T3.C
inner join #T2 on #T2.B2 = #T3.BL AND #T2.C2 = #T3.C AND #T2.A2 = #T1.A1
UNION ALL
SELECT Value1 A1, B1, C1, BR, BL, C, A2, B2, C2, Value2
FROM #T3 left join #T2 on #T2.B2 = #T3.BL and #T2.C2 = #T3.C
full join #T1 on #T1.B1 = #T3.BR and #T1.C1 = #T3.C AND #T2.A2 = #T1.A1
WHERE #T1.A1 is NULL
UNION ALL
SELECT Value1 A1, B1, C1, BR, BL, C, A2, B2, C2, Value2
FROM #T3 left join #T1 on #T1.B1 = #T3.BR and #T1.C1 = #T3.C
full join #T2 on #T2.B2 = #T3.BL and #T2.C2 = #T3.C AND #T2.A2 = #T1.A1
WHERE #T2.A2 is NULL
Однако я хотел бы найти более эффективный/элегантный способ сделать это, если он существует.
«Я пробовал разные подходы». Где один из них? Я этого не вижу. SO не является сайтом службы бесплатного кодирования. Опубликуйте свой запрос. Если не получится, постараемся помочь.
Похоже, вам нужно ПОЛНОЕ СОЕДИНЕНИЕ, опубликуйте свою попытку использовать его, чтобы мы могли его отладить.
Добавлены примеры кодов. Я пробовал различные комбинации объединений, но не получил того, что искал (это таблица, написанная от руки в первой части сообщения).
Четкое описание понятнее, чем нечеткое описание. Используйте достаточно слов, предложений и ссылок на примеры, чтобы сказать, какие строки появляются в результате с точки зрения строк, которые появляются во входных данных. Т.е. указать обстоятельства, при которых в результате появляется строка вида (A1, B1, C1, BR, BL, C, A2, B2, C2, Value2). Например, когда строка (t1.A1, t1.B1, t1.C1) появляется в T1 & A1=t1.A1 & B1=t1.B1 & C1=t1.C1 & ... ИЛИ ....





Я не уверен, но я думаю, что это даст вам результаты, которые вы ищете. (То, что вы ищете, немного неясно.)
Я не знаю, есть ли более простое решение, но его может и не быть, потому что вы ищете сворачивающиеся комбинации пересечений по правилам внутреннего соединения, а вам нужно внешнее соединение для включения «недостающих» записей.
SELECT Value1 A1, B1, C1, BR, BL, C, A2, B2, C2, Value2
FROM T3 inner join T1 on T1.B1 = T3.BR
inner join T2 on T2.B2 = T3.BL
WHERE A1 = A2 and C1 = C2
UNION ALL
SELECT Value1 A1, B1, C1, BR, BL, C, A2, B2, C2, Value2
FROM T3 inner join T1 on T1.B1 = T3.BR
left outer join T2 on T2.B2 = T3.BL
WHERE T2.B2 is NULL
UNION ALL
SELECT Value1 A1, B1, C1, BR, BL, C, A2, B2, C2, Value2
FROM T3 inner join T2 on T2.B2 = T3.BL
left outer join T1 on T1.B1 = T3.BR
WHERE T1.B1 is NULL
В результаты не будут включены записи из таблицы T3, которые не соответствуют ни T1, ни T2, но я не понимаю, нужны ли они вам.
Привет. То, что вы написали, не совсем то, что я ищу, но я понял вашу идею и преобразовал ее в запрос, который я ищу (см. Мое редактирование). Я действительно ищу решение, которое могло бы быть более элегантным/эффективным.
Что это за технология SQL? Опубликуйте, что вы пробовали для своих запросов. Также у вас есть 3 таблицы, из которых вы пытаетесь получить данные. Попробуйте сначала сделать только 2, затем получите данные, а затем добавьте 3-й.