全外连接同一个表的两个子集(Postgres 9.5)

时间:2017-03-24 20:51:51

标签: postgresql join

我想在同一个表的两个不同子集上进行完全外连接,我希望在不编写CTE或子查询的情况下执行此操作。我的数据看起来像这样:

with test as
(
select
  'auths' as source,
  'a1' as source_id,
  'peter' as name

union all

select
  'auths' as source,
  'a1' as source_id,
  'lauren' as name

union all

select
  'claims' as source,
  'c1' as source_id,
  'lauren' as name

union all

select
  'claims' as source,
  'c3' as source_id,
  'Jeff' as name
)

结果如下:

source  source_id   name
auths   a1          peter
auths   a1          lauren
claims  c1          lauren
claims  c3          Jeff

所以这里的想法是我在这个表中有两个来源,称之为" auths"和"索赔"。在这个特殊的例子中,名字叫劳伦'出现在源代码为' auths'的两行中。并声称'。名称彼得仅出现在' auths'杰夫的名字只出现在'声明'。

我想在表的两个子集上进行完全外连接,其中子集由source的值定义,连接条件由name指定。例如,

select 
  coalesce(auths.name, claims.name) as name,
  auths.source as auths_source,
  auths.source_id as auths_source_id,
  claims.source as claims_source,
  claims.source_id as claims_source_id
from (select * from test where source = 'auths') as auths
full outer join (select * from test where source = 'claims') as claims
  on auths.name = claims.name

,所需的结果如下所示

name    auths_source    auths_source_id claims_source   claims_source_id
peter   auths             a1        
lauren  auths             a1                claims            c1
Jeff                                        claims            c3

基本上,我们的想法是,当匹配时,它会存储在同一行中。如果不匹配,则会将其存储为两个单独的行。

我想知道是否可以在不使用子查询的情况下执行此操作。例如,我试过

select
  coalesce(auths.name, claims.name) as name,
  auths.source as auths_source,
  auths.source_id as auths_source_id,
  claims.source as claims_source,
  claims.source_id as claims_source_id
from test as auths
  full outer join test as claims
    on auths.source = 'auths'
      and claims.source = 'claims'
      and auths.name = claims.name

但这不起作用,因为它是一个完整的外部联接,结果仍会返回testauths claims中的所有内容。例如,从此返回的结果是:

name    auths_source    auths_source_id claims_source   claims_source_id
peter   auths                  a1       
lauren  auths                  a1           claims             c1
lauren  claims                 c1       
Jeff    claims                 c3       
peter                                       auths              a1
Jeff                                        claims             c3
lauren                                      auths              a1

这不是我想要的,因为auths_source中有额外的行,其值为claims(类似于claims_source,其值为auths且这种情况正在发生因为完整的外部联接会返回所有行,无论如何。

谢谢!

1 个答案:

答案 0 :(得分:0)

试试这个:

select
  coalesce(auths.name, claims.name) as name,
  auths.source as auths_source,
  auths.source_id as auths_source_id,
  claims.source as claims_source,
  claims.source_id as claims_source_id
from test as auths
full outer join test as claims
  on auths.source = 'auths'
  and claims.source = 'claims'
  and auths.name = claims.name
where coalesce(auths.source, 'auths') = 'auths' 
  and coalesce(claims.source, 'claims') = 'claims'

这基本上是你的陈述,增加了where子句。