【问题标题】:Union merging different columns联合合并不同的列
【发布时间】:2016-08-02 11:18:16
【问题描述】:

我有两张桌子:

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 行具有相同的 dataid 时,我想从 Table1 中获取“NAME”列和某种聚合 FACTOR,例如“1,2”或 3

【问题讨论】:

  • 第二张桌子上的约翰和加里怎么了?
  • 没关系。安和皮特很重要,约翰和加里不重要。
  • 那么你不需要一个 UNION。请说明您的要求。您是否只是为 (dataid, factor) 做一个 UNION,如果存在则从第一个表中选择名称,如果不存在,则从第二个表中获取它?
  • 那么查询应该如何知道 Ann 和 Piter 重要,而 John 和 Garry 不重要?看来您正在使用 John 和 Garry 的 FACTOR 值并将它们附加到 Ann 和 Piter 的值。查询应该如何确定这一点?

标签: sql oracle merge union


【解决方案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;

【讨论】:

  • 您是否注意到 OP 表的联合(或全部联合)与他/她声称的输出不匹配?
  • [After your edits:] full outer join 不起作用,他/她在两个表中对同一个 id 有不同的名称,并想先选择 table1 中的内容;聚合函数也不起作用(没有额外的工作)。
【解决方案2】:

这样的事情应该可以工作。在您的实际情况下,您不需要前两个 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.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-25
    • 2022-08-18
    相关资源
    最近更新 更多