sql >> Base de Datos >  >> RDS >> Oracle

Oracle SQL - declaración de caso dinámico

Necesita una función PIVOT con definición de columnas dinámicas. La forma más sencilla es pivotar 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)
)  

Después de que necesite procesar datos 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 admite la definición de columnas dinámicas (for source in (select distinct t.source from tst_data t) ) sin embargo, devuelve datos XML. Extractvalue y xmltable Las funciones permiten consultar columnas particulares del XML en el lado del servidor, pero debe especificar los nombres de los campos por adelantado. Así que supongo que lo analizaré en el lado del cliente.

Si desea hacer todo en DB-layer, existe otro enfoque. PIVOT (no XML) requiere nombres de columnas for source in ('INTERNET', 'DEMO', 'COM', ...) . Es posible generar una consulta de este tipo y devolver un cursor al lado del 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;

No conozco ningún método para crear una consulta simple sin tipo desde el cursor (en el lado del servidor), por lo que si desea utilizar una consulta SQL simple, hágalo en dos pasos:

  1. Generar una consulta PIVOT con columnas con nombre en la función PL/SQL;
  2. Ejecute la consulta desde su cliente.