【发布时间】:2021-07-21 11:03:04
【问题描述】:
我有什么
我有多个带有主键 key 和值的表。每个键可能存在于所有表中,也可能只存在于表的子集中。
以下是示例表:
表 1:
| key | value |
|---|---|
| A | 1 |
| C | 3 |
Tab2:
| key | value |
|---|---|
| A | 10 |
| D | 10 |
Tab3:
| key | value |
|---|---|
| B | 20 |
| D | 10 |
我想要什么
我想以这样一种方式加入表格,即每个现有键获得一行,每个表格获得一列。如果其中一个表中不存在键,则应假定为null。所以对于上面的例子,我想得到这个结果:
| key | tab1 | tab2 | tab3 |
|---|---|---|---|
| A | 1 | 10 | NULL |
| B | NULL | NULL | 20 |
| C | 3 | NULL | NULL |
| D | NULL | 10 | 10 |
到目前为止我尝试过的内容
这是我想出的,可行的:
with tab1 as (
select * from (values('A', 1), ('C', 3))x(key, value)
),
tab2 as (
select * from (values('A', 10), ('D', 10))x(key, value)
),
tab3 as (
select * from (values('B', 20), ('D', 10))x(key, value)
)
select
coalesce(tab1.key, tab2.key, tab3.key) "key",
tab1.value tab1,
tab2.value tab2,
tab3.value tab3
from tab1
full outer join tab2 on tab2.key = tab1.key
full outer join tab3 on tab3.key = coalesce(tab1.key, tab2.key)
order by coalesce(tab1.key, tab2.key, tab3.key)
问题
在上面的情况下,我的查询看起来还不错,但是在实际情况下,我需要连接 6 个表,并且键实际上分布在三列中。这会导致很长的连接语句。第六个表的语句如下所示:
full outer join tab6
on tab6.key1 = coalesce(tab1.key1, tab2.key1, tab3.key1, tab4.key1, tab5.key1)
and tab6.key2 = coalesce(tab1.key2, tab2.key2, tab3.key2, tab4.key2, tab5.key2)
and tab6.key3 = coalesce(tab1.key3, tab2.key3, tab3.key3, tab4.key3, tab5.key3)
从代码质量的角度来看,复制和粘贴coalesce-calls 的激增有些令人不安。
还有其他更简单的方法可以获得我想要的结果吗?
【问题讨论】:
标签: sql postgresql