Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Oracle SQL - dynamische Case-Anweisung

Sie benötigen eine PIVOT-Funktion mit dynamischer Spaltendefinition. Der einfachste Weg ist 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)
)  

Nachdem Sie XML-Daten verarbeiten müssen:

<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 unterstützt die dynamische Spaltendefinition (for source in (select distinct t.source from tst_data t)). ) gibt jedoch XML-Daten zurück. Extractvalue und xmltable Funktionen erlauben es, bestimmte Spalten aus dem XML auf der Serverseite abzufragen, aber Sie müssen Feldnamen im Voraus angeben. Also nehme ich an, es auf Client-Seite zu analysieren.

Wenn Sie alles auf DB-Layer machen wollen, gibt es einen anderen Ansatz. PIVOT (nicht XML) erfordert Spaltennamen for source in ('INTERNET', 'DEMO', 'COM', ...) . Es ist möglich, eine solche Abfrage zu generieren und einen Cursor zurückzugeben zur Clientseite:

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;

Ich kenne keine Methode, um eine einfache nicht typisierte Abfrage vom Cursor (auf der Serverseite) zu erstellen. Wenn Sie also eine einfache SQL-Abfrage verwenden möchten, tun Sie dies in zwei Schritten:

  1. Generieren Sie eine PIVOT-Abfrage mit benannten Spalten in der PL/SQL-Funktion;
  2. Führen Sie die Abfrage von Ihrem Client aus.