我正在尝试在三个表之间匹配记录,两个表是要匹配的数据,第三个表是一个中心表,告诉我应该如何匹配记录。
一个例子将比冗长的演讲更清楚:
表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
这就是我得到的result。关闭,但是我希望BR,BL和C永远不要为NULL,因为在那之后我有一些逻辑。这些列不必在最后一行为空,可以将其与#T3中的一行匹配。
整个困难都在AND #T2.A2 = #T1.A1
中:如果存在这样的记录,我希望它匹配,但是如果不存在,我希望它表现得好像第二个联接是#T2.B2 = #T3.BL AND #T2.C2 = #T3.C
上的LEFT JOIN一样< / p>
编辑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
但是我想找到一种更有效/更优雅的方法来做到这一点,它确实存在。
答案 0 :(得分:0)
我不确定,但是我认为这会为您提供所需的结果。 (您正在寻找的东西还不清楚。)
我不知道是否有一个更简单的解决方案,但可能没有,因为您正在根据内部联接的规则寻找折叠交叉组合,但是您需要一个外部联接来包含“缺失”记录。 / p>
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