我希望根据参与连接的所有表中存在的一组列加入两个(或更多)表。换句话说,我希望基于交集列连接表。但是,每个表都有额外的列,这些列对于该表是唯一的。
#:一个数字
- :NULL
表A
+------+------+------+
| Col1 | Col2 | ColA |
+------+------+------+
| A | A | # |
| A | B | # |
+------+------+------+
表B
+------+------+------+
| Col1 | Col2 | ColB |
+------+------+------+
| A | A | # |
| B | B | # |
+------+------+------+
结果
+------+------+------+------+
| Col1 | Col2 | ColA | ColB |
+------+------+------+------+
| A | A | # | # |
| A | B | # | - |
| B | B | - | # |
+------+------+------+------+
我提出了一个解决方案,但性能很糟糕,性能是一个问题。我不想用这个解决方案污染你。我更愿意对此有一双新的看法:)
期待看到您的解决方案。感谢您的时间。非常感谢。
感谢所有回复。 然而,似乎我没有充分解释这个问题。 (Haven尚未测试所有答案)
但请注意表B中有一行在表A中不存在。
Table B
+------+------+------+
| Col1 | Col2 | ColB |
+------+------+------+
| B | B | # |
+------+------+------+
表A反之亦然。
解决方案我已经在所有列的交叉点上将所有表格联合起来以生成骨架。
Skeleton:
SELECT Col1, Col2 FROM TableA
UNION
SELECT Col1, Col2 FROM TableB
一旦我拥有了骨架,我就为每张桌子留下了外部。
LEFT OUTER JOIN TableA AS a ON a.Col1=skeleton.Col1 AND a.Col2=skeleton.Col2
LEFT OUTER JOIN TableB AS b ON b.Col1=skeleton.Col1 AND b.Col2=skeleton.Col2
所以最后的查询看起来像这个
SELECT s.*, a.ColA, b.ColB
FROM
(
SELECT Col1, Col2
FROM TableA
UNION
SELECT Col1, Col2
FROM TableB
) s
LEFT OUTER JOIN TableA a ON a.Col1=s.Col1 AND a.Col2=s.Col2
LEFT OUTER JOIN TableB b ON b.Col1=s.Col1 AND b.Col2=s.Col2
答案 0 :(得分:3)
只是full outer join
:
select coalesce(a.Col1, b.Col1) as Col1
. coalesce(a.Col2, b.Col2) as Col2
, a.ColA
, b.ColB
from A a
full outer join
B b
on a.Col1 = b.Col1
and a.COl2 = b.Col2
答案 1 :(得分:0)
这可能会有所帮助:
SELECT Col1, Col2, ColA
FROM A
GROUP BY Col1, Col2, ColA
UNION ALL
SELECT Col1, Col2, ColB
FROM B
GROUP BY ColB
或者看看这里:
答案 2 :(得分:0)
您可以使用Union解析双外连接:
SELECT
TableA.Col1,TableA.Col2,
TableA.ColA,TableB.ColB
FROM TableA
LEFT JOIN TableB ON TableA.Col1=TableB.Col1 AND TableA.Col2=TableB.Col2
UNION
SELECT
TableB.Col1,TableB.Col2,
TableA.ColA,TableB.ColB
FROM TableB
LEFT JOIN TableA ON TableA.Col1=TableB.Col1 AND TableA.Col2=TableB.Col2
答案 3 :(得分:0)
哦,我的。如实你想要的。
-- Sample data.
declare @TableA as Table ( Col1 VarChar(8), Col2 VarChar(8), ColA Int NULL )
insert into @TableA ( Col1, Col2, ColA ) values
( 'A', 'A', 42 ), ( 'A', 'B', 7 )
declare @TableB as Table ( Col1 VarChar(8), Col2 VarChar(8), ColB Int NULL )
insert into @TableB ( Col1, Col2, ColB ) values
( 'A', 'A', 999 ), ( 'B', 'B', -1 )
select * from @TableA
select * from @TableB
-- The query. Use the aggregate(s) of your choice: SUM, MIN, MAX, AVG.
select Col1, Col2, Sum( ColA ), Sum( ColB )
from (
select A.Col1, A.Col2, A.ColA, Cast( NULL as Int ) as [ColB]
from @TableA as A
union all
select B.Col1, B.Col2, Cast( NULL as Int ), B.ColB
from @TableB as B ) as Edgar
group by Col1, Col2