Oracle
 sql >> Database >  >> RDS >> Oracle

come combinare due valori diversi da una tabella di un cliente in una riga

Devi GROUP BY id e la condizione "più di un ordine" va in un HAVING clausola (perché è un vincolo su ciascun gruppo, non su ogni singola riga nei dati di input). L'aggregazione avviene con LISTAGG .

with
     test_data ( id, product, code ) as (
       select 1, 'Apple' , 145 from dual union all
       select 1, 'Grapes', 146 from dual union all
       select 2, 'Orange', 147 from dual union all
       select 2, 'Apple' , 145 from dual union all
       select 2, 'Plum'  , 148 from dual union all
       select 3, 'Grapes', 146 from dual union all
       select 3, 'Orange', 147 from dual union all
       select 4, 'Grapes', 146 from dual union all
       select 5, 'Orange', 147 from dual
     )
--  End of test data (not part of the solution). Query begins below this line.
select   id, listagg(code, ' | ') within group (order by id) as codes
from     test_data
group by id
having   count(*) > 1
;

ID  CODE
--  ---------------
 1  145 | 146
 2  145 | 147 | 148
 3  146 | 147

Tuttavia, in Oracle 10 non hai LISTAGG() . Prima di Oracle 11.2, un modo comune per ottenere lo stesso risultato era utilizzare query gerarchiche, come di seguito:

select id, ltrim(sys_connect_by_path(code, ' | '), ' | ') as codes
from   (
         select id, code,
                row_number() over (partition by id order by code) as rn
         from   test_data
       )
where connect_by_isleaf = 1 and level > 1
connect by rn = prior rn + 1
       and prior id = id
       and prior sys_guid() is not null
start with rn = 1
;

MODIFICATO :

Se è necessario prima "distinguere" CODE ripetuto per lo stesso ID, quindi - utilizzando la seconda soluzione - sono necessarie le seguenti modifiche, entrambe nella subquery più interna:

  • cambia SELECT ID, CODE, ... a SELECT DISTINCT ID, CODE, ...

  • cambia ROW_NUMBER() a DENSE_RANK()