2016-07-20 25 views
0

Ich habe die folgende TabelleSQL LISTAGG für verschiedene Arten von Werten

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 

ich eine SQL-Tabelle wie diese

name phone    address 

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

machen wollen habe ich versucht, diese 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 

Und es funktioniert nicht. Ich weiß, weil die WHERE-Klausel nicht da ist, wo sie sein muss. Aber wo kann ich die Einschränkungen einfügen? Wenn ich es wie

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 

tun würde es aussehen

name phone       address 

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

Antwort

0

so etwas wie dies auch sein mag, aber ich denke, Sie DB-Design ist sehr schlecht

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 

Ausgabe lautet:

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

wenn Bestellung Telefonnummern (Handy, h ome) sind nicht wichtig Versuchen Sie diesen Codeblock:

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 

Geben Sie dieses Ergebnis:

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