Oracle
 sql >> Base de données >  >> RDS >> Oracle

Oracle SQL - déclaration de cas dynamique

Vous avez besoin d'une fonction PIVOT avec une définition de colonnes dynamiques. Le moyen le plus simple est 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)
)  

Une fois que vous avez besoin de traiter des données 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 prend en charge la définition de colonnes dynamiques (for source in (select distinct t.source from tst_data t) ) mais il renvoie des données XML. Extractvalue et xmltable Les fonctions permettent d'interroger des colonnes particulières à partir du XML côté serveur, mais vous devez spécifier les noms de champ à l'avance. Je suppose donc de l'analyser côté client.

Si vous voulez tout faire sur la couche DB, il existe une autre approche. PIVOT (pas XML) nécessite des noms de colonnes for source in ('INTERNET', 'DEMO', 'COM', ...) . Il est possible de générer une telle requête et de renvoyer un curseur côté client :

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;

Je ne connais aucune méthode pour créer une requête simple non typée à partir du curseur (côté serveur), donc si vous souhaitez utiliser une requête SQL simple, faites-le en deux étapes :

  1. Générer une requête PIVOT avec des colonnes nommées dans la fonction PL/SQL ;
  2. Exécutez la requête depuis votre client.