我有一个查询,我需要在一个列上加入大量的表,当任何表中的任何记录与该列匹配时,应该连接记录.一个例子:
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>
Run Code Online (Sandbox Code Playgroud)
应该返回如下结果集:
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
Run Code Online (Sandbox Code Playgroud)
你可以写这样的连接:
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
Run Code Online (Sandbox Code Playgroud)
但这似乎很荒谬,并且随着列数的增加而迅速失控(n以这种方式连接表需要n*(n-1)/2条件).有更好的方法啊.有没有人有任何想法?
做你想做的事有三种方法.您已经探索过该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)
Run Code Online (Sandbox Code Playgroud)
第二种方式有两个子部分.如果你有一张所有id的表,那就太好了.只需使用left join:
AllIds ai left outer join
A
on ai.id = A.id left outer join
B
on ai.id = B.id . . .
Run Code Online (Sandbox Code Playgroud)
如果你没有,你可以制作一个:
(select id from a union
select id from b union
select id from c union
select id from d
) AllIds left outer join
. . .
Run Code Online (Sandbox Code Playgroud)
第三种方式是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;
Run Code Online (Sandbox Code Playgroud)
它们具有不同的性能特征,具体取决于表,索引和数据库.实际上,我经常在大表上使用第二个选项.
| 归档时间: |
|
| 查看次数: |
589 次 |
| 最近记录: |