Você precisa de uma função PIVOT com definição de colunas dinâmicas. A maneira mais simples é pivot xml:
create table tst_data (id int primary key, source varchar2(255));
insert into tst_data values (1, 'INTERNET');
insert into tst_data values (2, 'DEMO');
insert into tst_data values (3, 'INTERNET');
insert into tst_data values (4, 'SALES');
insert into tst_data values (5, 'INTERNET');
insert into tst_data values (6, 'DEMO');
insert into tst_data values (7, 'INTERNET');
insert into tst_data values (8, 'COM');
commit;
select * from (
select source from tst_data
)
pivot xml
(
count(1)
for source in (select distinct t.source from tst_data t)
)
Depois que você precisar processar dados XML:
<PivotSet>
<item>
<column name = "SOURCE">COM</column>
<column name = "COUNT(1)">1</column>
</item>
<item>
<column name = "SOURCE">DEMO</column>
<column name = "COUNT(1)">2</column>
</item>
<item>
<column name = "SOURCE">INTERNET</column>
<column name = "COUNT(1)">4</column>
</item>
<item>
<column name = "SOURCE">SALES</column>
<column name = "COUNT(1)">1</column>
</item>
</PivotSet>
PIVOT XML
suporta definição de colunas dinâmicas (for source in (select distinct t.source from tst_data t)
), mas retorna dados XML. Extractvalue
e xmltable
As funções permitem consultar colunas específicas do XML no lado do servidor, mas você precisa especificar os nomes dos campos antecipadamente. Então eu assumo para analisá-lo no lado do cliente. Se você quiser fazer tudo na camada de banco de dados, há outra abordagem.
PIVOT
(não XML) requer nomes de colunas for source in ('INTERNET', 'DEMO', 'COM', ...)
. É possível gerar tal consulta e retornar um cursor para o lado do cliente:CREATE OR REPLACE FUNCTION FUNCTION1 RETURN SYS_REFCURSOR AS
cur sys_refcursor;
BEGIN
open cur for 'select * from dual'; // generate PIVOT query here
RETURN cur;
END FUNCTION1;
Não conheço nenhum método para criar uma consulta simples sem tipo a partir do cursor (no lado do servidor), portanto, se você deseja usar uma consulta SQL simples, faça isso em duas etapas:
- Gere uma consulta PIVOT com colunas nomeadas na função PL/SQL;
- Execute a consulta do seu cliente.