我有一个查询,我需要在一个列上加入大量表,当来自任何表的任何记录在该列上匹配时,应该连接记录。一个例子:
A
----------
id | a_value
----------
1 | foo
2 | bar
B
----------
id | b_value
----------
2 | cad
3 | qud
C
----------
id | c_value
----------
1 | fiz
4 | buz
D
----------
id | d_value
----------
5 | sas
6 | tos
SELECT id, a_value, b_value, c_value, d_value FROM <join A, B, C, D by id>
应返回如下结果集:
results
------------------------------------------
id | a_value | b_value | c_value | d_value
------------------------------------------
1 | foo | null | fiz | null
2 | bar | cad | null | null
3 | null | qud | null | null
4 | null | null | buz | null
5 | null | null | null | sas
6 | null | null | null | tos
您可以像这样编写联接:
A FULL JOIN B ON A.id = B.id
FULL JOIN C ON A.id = C.id OR B.id = C.id
FULL JOIN D ON A.id = D.id OR B.id = D.id OR C.id = D.id
但这似乎很荒谬,并且随着列数的增加而迅速失控(以这种方式加入n
表需要n*(n-1)/2
条件)。有更好的方法啊。有没有人有任何想法?
答案 0 :(得分:6)
有三种方法可以做你想要的。您已经探索过full outer join
选项,并发现它需要。顺便说一下,你可以将它简化为:
A FULL JOIN
B
ON A.id = B.id FULL JOIN
C
ON C.id = coalesce(A.id, B.id) FULL JOIN
D
ON D.id = coalesce(A.id, B.id, C.ID)
第二种方式有两个子部分。如果你有一张所有id的表,那就太好了。只需使用left join
:
AllIds ai left outer join
A
on ai.id = A.id left outer join
B
on ai.id = B.id . . .
如果你没有,你可以制作一个:
(select id from a union
select id from b union
select id from c union
select id from d
) AllIds left outer join
. . .
第三种方式是union all
方式:
select id, max(a_value) as a_value, max(b_value) as b_value,
max(c_value) as c_value, max(d_value) as d_value
from (select a.id, a_value, NULL as b_value, NULL as c_value, NULL as d_value
from a
union all
select b.id, NULL, b_value, NULL, NULL
from b
union all
select c.id, NULL, NULL, c_value, NULL
from c
union all
select d.id, NULL, NULL, NULL, d_value
from d
) t
group by id;
根据表,索引和数据库,它们具有不同的性能特征。实际上,我经常在大表上使用第二个选项。