2016-08-02 64 views
0

我有两个表:联盟合并不同列

Table1

DATAID| NAME | FACTOR 

1 | Ann | 1 
2 | Kate | 1 
3 | Piter | 1 

Table2

DATAID| NAME | FACTOR 

1 | John | 2 
6 | Arse | 2 
3 | Garry | 2 

我想UNION这些表,并得到这样的结果:

DATAID| NAME | FACTOR 

1 | Ann  | 1,2 
2 | Kate | 1 
3 | Piter | 1,2 
6 | Arse | 2 

因此,当有2行与同一数据ID,我想获得从表1“姓名”列和某种聚合因子,例如“1,2”或3

+2

什么第二个表发生了约翰和加里? – mathguy

+0

这并不重要。安和皮特很重要,约翰和加里没有。 – ifuwannaride

+0

然后你不想要一个联盟。请澄清你的要求。你只是简单地为(dataid,factor)做一个UNION,如果它存在,你从第一个表中选择名称,如果不存在,你从第二个表中取出它? – mathguy

回答

1

一种方法是使用listagg()

select dataid, name, 
     listagg(factor, ',') within group (order by factor) as factors 
from ((select dataid, name, factor from table1 t1 
    ) union all 
     (select dataid, name, factor from table2 t2 
    ) 
    ) t 
group by dataid, name; 

注:我注意到名称是而不是对于给定的id是相同的。您可以使用聚合功能选择一个。

或者,如果你只有一个行中的每个表,你可以使用一个full outer join

select coalesce(t1.dataid, t2.dataid) as dataid, 
     coalesce(t1.name, t2.name) as name, 
     trim(leading ',' from coalesce(',' || t1.factor, ',') || coalesce(',' || t2.factor, '') as factors 
from t1 full outer join 
    t2 
    on t1.dataid = t2.dataid; 
+0

您是否注意到OP表中的工会(或工会全部)与他/她的意图输出不匹配? – mathguy

+0

[编辑完成后]完整的外连接不起作用,他/她对两个表中的相同ID有不同的名称,并且希望先选择table1中的内容;一个聚合函数也不会工作(没有额外的工作)。 – mathguy

+0

mathguy,正好。 – ifuwannaride

0

这样的事情应该工作。在你的实际情况中,你将不需要前两个CTE(我为增加测试添加的WITH子句中的子查询)。

with 
    table1 (dataid, name, factor) as (
     select 1, 'Ann' , 1 from dual union all 
     select 2, 'Kate' , 1 from dual union all 
     select 3, 'Piter', 1 from dual 
    ), 
    table2 (dataid, name, factor) as (
     select 1, 'John' , 2 from dual union all 
     select 6, 'Arse' , 2 from dual union all 
     select 3, 'Garry', 2 from dual 
    ), 
    u (dataid, name, factor, source) as (
     select dataid, name, factor, 1 from table1 
     union all 
     select dataid, name, factor, 2 from table2 
    ), 
    z (dataid, name, factor) as (
     select dataid, first_value(name) over (partition by dataid order by source), 
       factor 
     from u 
    ) 
select dataid, name, 
     listagg(factor, ',') within group (order by factor) as factor 
from z 
group by dataid, name 
order by dataid 
; 

输出:

DATAID NAME FACTOR 
------- ----- --------- 
     1 Ann 1,2 
     2 Kate 1 
     3 Piter 1,2 
     6 Arse 2 

4 rows selected.