SQL LISTAGG用于不同类型的值

时间:2016-07-20 03:51:03

标签: sql oracle listagg

我有下表

name   type            value 

a      mobile          123456  
a      home tel        456789  
a      Office addr     add1  
a      home addr       add2  
b      mobile          456456  
b      home tel        123123  
b      Office addr     add3  
b      home addr       add4  

我想制作一个像这样的SQL表

name    phone             address

a       123456; 456789    add1; add2  
b       456456; 123123    add3; add4  

我试过这个SQL:

SELECT name, 
LISTAGG(t.CONTACT_INFO,';')
               WITHIN GROUP (ORDER BY type) AS phone where type in ('mobile', 'home tel'),
LISTAGG(t.CONTACT_INFO,';')
               WITHIN GROUP (ORDER BY type) AS address where type in ('Office addr', 'home addr')
FROM table t
  GROUP BY name

它不起作用。我知道因为WHERE子句不是它需要的地方。但是我可以在哪里插入限制?如果我这样做

SELECT name, 
LISTAGG(t.CONTACT_INFO,';')
               WITHIN GROUP (ORDER BY type) AS phone,
LISTAGG(t.CONTACT_INFO,';')
               WITHIN GROUP (ORDER BY type) AS address
FROM table t
  GROUP BY name

看起来像

name    phone                         address

a       123456; 456789;add1; add2     123456; 456789;add1; add2  
b       456456; 123123;add3; add4     456456; 123123;add3; add4  

2 个答案:

答案 0 :(得分:0)

可能是这样的,但我认为数据库设计非常糟糕

with a(name,type,value ) as (select 'a','mobile','123456' from dual union all
                             select 'a','home tel','456789' from dual union all
                             select 'a','Office addr', 'add1' from dual union all
                             select 'a','home addr','add2' from dual union all
                             select 'b','mobile','456456' from dual union all
                             select 'b','home tel','123123' from dual union all
                             select 'b','Office addr','add3' from dual union all
                             select 'b','home addr', 'add4' from dual  )
select a1.name,
       Listagg(a1.value, ';') Within Group (order by a1.type desc) phone,
       Listagg(a2.value, ';') Within Group (order by a2.type) address
  from a a1 inner join a a2 
        on decode(a1.type,'mobile','Office addr','home tel','home addr') = a2.type and a1.name = a2.name
group by a1.name

输出是:

a   123456;456789   add1;add2
b   456456;123123   add3;add4

答案 1 :(得分:0)

如果订购电话号码(移动电话,家庭电话)不重要 试试这个代码块:

select t2.name
      ,listagg(t2.phone
              ,';') within group(order by t2.phone) as phone
      ,listagg(t2.addresss
              ,';') within group(order by t2.addresss) as addresss
  from (select t.name
              ,case
                 when t.type in ('mobile'
                                ,'home tel') then
                  listagg(t.value
                         ,';') within group(order by t.type)
                 else
                  null
               end as phone
              ,case
                 when t.type in ('Office addr'
                                ,'home addr') then
                  listagg(t.value
                         ,';') within group(order by t.type)
                 else
                  null
               end as addresss
          from table t
         group by t.name
                 ,t.type) t2
 group by t2.name

给出这个结果:

 a   123456;456789   add1;add2
 b   123123;456456   add3;add4