Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Oracle SQL - instrução case dinâmica


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:
  1. Gere uma consulta PIVOT com colunas nomeadas na função PL/SQL;
  2. Execute a consulta do seu cliente.