Vou assumir que a
PRIORITY
coluna é sempre 1 quando há um "produto principal" e nunca 1 em qualquer outro momento. A partir de seus dados, também parece que cada cliente tem apenas um produto "principal". Eu vou assumir que isso é verdade. Se não for, você deve ter outra coluna para distinguir os grupos de produtos. Você pode simplesmente adicionar isso no abaixo. A resposta complicada/eficiente pode ser a seguinte:
select customer
, max(product) keep (dense_rank first order by priority) as main_product
, listagg(case when priority = 2 then product end, ', ')
within group (order by product) as sub_product
from products
group by customer
SQL Fiddle
Por cliente, o
PRODUCT
A coluna assume que cada cliente tem um produto principal e, em seguida, obtém o primeiro produto em ordem de prioridade. A segunda coluna leva apenas onde a prioridade é 2 e usa a função de concatenação de strings LISTAGG() para concatenar seus valores juntos. Eu recomendo o post do blog de Rob van Wijk sobre a cláusula KEEP.
Uma solução SQL mais padrão ficaria assim:
select a.customer, a.product as main_product
, listagg(b.product, ', ') within group (order by b.product) as sub_product
from products a
join products b
on a.customer = b.customer
where a.priority = 1
and b.priority = 2
group by a.customer, a.product
ou seja, encontre tudo que tenha prioridade 1, use isso para gerar suas duas linhas e, em seguida, obtenha tudo com prioridade 2 e agregue-as.