我有一组表有很多不同的列(比如在SELECT
子句中手动列出它们会是一件坏事。)
我想将它们组合在一起类似于UNION
结果,除了UNION要求所有表中的列完全匹配(如果它们不是,则必须添加虚拟NULL值)。
所以:
Table1
Domain | Field1 | Field2 | etc
foo.com 1 2
bar.com 0 1
Table2
Domain | FieldX | FieldY | etc
foo.com 3 9
baz.com 10 11
Table3
Domain | FieldA | FieldB | etc
baz.com 1 2
qux.com 123 56
期望的结果:
Domain | Field1 | Field2 | ... | FieldX | FieldY | ... | FieldA | FieldB | ...
foo.com 1 2 3 9
bar.com 0 1
baz.com 10 11 1 2
qux.com 123 56
我尝试使用FULL OUTER JOIN
作为替代方案,但由于它是一个OUTER连接,它为我提供了过多的数据。
这是一个SQLFiddle:http://sqlfiddle.com/#!6/3fa84/2
答案 0 :(得分:1)
首先使用UNION
(不是UNION ALL
)制作所有不同域名的列表(此处假设每个表中的域名都是唯一的)然后LEFT JOIN
所有你的桌子。
DECLARE @Table1 TABLE ( [Domain] varchar(50), X1 int, X2 int );
DECLARE @Table2 TABLE ( [Domain] varchar(50), Y1 int, Y2 int );
DECLARE @Table3 TABLE ( [Domain] varchar(50), Z1 int, Z2 int );
INSERT INTO @Table1 ( [Domain], X1, X2 ) VALUES
( 'Foo.com', 1, 2 ),
( 'Bar.com', 0, 1 );
INSERT INTO @Table2 ( [Domain], Y1, Y2 ) VALUES
( 'Blah.com', 3, 0 ),
( 'Bar.com', 2, 1 ),
( 'reddit.com', -1, -2 );
INSERT INTO @Table3 ( [Domain], Z1, Z2 ) VALUES
( 'Gggg.com', 22, 33 ),
( 'Foo.com', 22, 44 ),
( 'bar.com', 50, 51 ),
( 'reddit.com', 10, 20 );
WITH
CTE_Domains
AS
(
SELECT Domain FROM @Table1
UNION
SELECT Domain FROM @Table2
UNION
SELECT Domain FROM @Table3
)
SELECT
CTE_Domains.Domain
,X1
,X2
,Y1
,Y2
,Z1
,Z2
FROM
CTE_Domains
LEFT JOIN @Table1 AS T1 ON T1.Domain = CTE_Domains.Domain
LEFT JOIN @Table2 AS T2 ON T2.Domain = CTE_Domains.Domain
LEFT JOIN @Table3 AS T3 ON T3.Domain = CTE_Domains.Domain
ORDER BY CTE_Domains.Domain;
这是结果集:
Domain X1 X2 Y1 Y2 Z1 Z2
Bar.com 0 1 2 1 50 51
Blah.com NULL NULL 3 0 NULL NULL
Foo.com 1 2 NULL NULL 22 44
Gggg.com NULL NULL NULL NULL 22 33
reddit.com NULL NULL -1 -2 10 20
如果您编写SELECT *
而不是显式列列表,则结果集将为此。每个连接表都会重复Domain
列。
Domain Domain X1 X2 Domain Y1 Y2 Domain Z1 Z2
Bar.com Bar.com 0 1 Bar.com 2 1 bar.com 50 51
Blah.com NULL NULL NULL Blah.com 3 0 NULL NULL NULL
Foo.com Foo.com 1 2 NULL NULL NULL Foo.com 22 44
Gggg.com NULL NULL NULL NULL NULL NULL Gggg.com 22 33
reddit.com NULL NULL NULL reddit.com -1 -2 reddit.com 10 20
答案 1 :(得分:0)
这样的东西可以给你你想要的没有多余的行:
SELECT COALESCE(t3.Domain, t1t2.Domain) AS Domain,
t1t2.X1, t1t2.X2, t1t2.Y1, t1t2.Y2,
t3.Z1, t3.Z2
FROM Table3 AS t3
FULL OUTER JOIN (
SELECT COALESCE(t1.Domain, t2.Domain) AS Domain, t1.X1, t1.X2, t2.Y1, t2.Y2
FROM Table1 AS t1
FULL OUTER JOIN Table2 AS t2 ON t1.Domain = t2.Domain ) AS t1t2
ON t3.Domain = t1t2.Domain