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

zwei Spalten Pivotierung in Oracle SQL

Für definierte Anzahl von Wertepaaren in den Spalten tname, ttype Sie können die folgende Abfrage verwenden (beachten Sie, dass ich Ihre Spaltennamen aus dem Beispiel geändert habe, weil Sie dort Oracle-Schlüsselwörter verwendet haben, außerdem habe ich die Tabelle als tasks benannt , also müssen Sie diese Daten überall im Code in Ihre echten Spaltennamen und Tabellennamen ändern):

select * from tasks 
pivot (max(tdate) for (tname, ttype) in 
  (('DG1','CF') DG1_CF, ('M0','A')  M0_A,  ('M0','POR') M0_POR,
   ('M1','A'  ) M1_A,   ('M1','CF') M1_CF, ('M2','A')   M2_A)));

Für eine dynamische Anzahl von Möglichkeiten benötigen Sie eine Prozedur, um diese Abfrage zu "erstellen". Hier habe ich view verwendet dafür. Kopieren Sie den Prozedurcode und kompilieren Sie ihn. Wenn sich Daten in Ihrer Tabelle ändern, müssen Sie zuerst die Prozedur ausführen und dann einfach aus der von der Prozedur erstellten Ansicht auswählen. Damit Ihr Schema ordnungsgemäß ausgeführt werden kann, müssen Berechtigungen zum Erstellen von Ansichten gewährt werden.

execute create_tasks_view;
select * from v_tasks;

anonymous block completed
   ID DG1_CF     M0_A       M0_POR     M1_A       M1_CF      M2_A     
----- ---------- ---------- ---------- ---------- ---------- ----------
45000 2015-03-02 2015-02-01 2015-03-11 2015-02-03 2015-03-01 2015-02-04 
44400 2015-02-02 2015-01-01 2015-02-11 2015-01-03 2015-02-01 2015-01-04

Natürlich können Sie die Reihenfolge der Zeilen und Spalten beliebig ändern, indem Sie order by hinzufügen oder ändern Teile im Verfahrenscode:

create or replace procedure create_tasks_view as 
  v_sql varchar2(32767) := '';
begin
  for v in (select distinct tname, ttype from tasks order by tname, ttype) 
  loop
    v_sql := v_sql || '(''' || v.tname || ''',''' || v.ttype || ''') '
      ||v.tname||'_'||v.ttype||',';
  end loop;
  v_sql := 'create or replace view v_tasks as '
    ||'select * from tasks pivot (max(tdate) for (tname, ttype) in ('
    ||rtrim(v_sql, ', ')||'))'; 
  execute immediate v_sql;
end create_tasks_view;

Ich glaube, es gibt auch eine universellere Lösung für Ihre Frage im Link, den ich Ihnen in Kommentaren gegeben habe:Dynamisches SQL-Pivoting... . Es sieht sehr vielversprechend aus, lesen Sie einfach den Abschnitt Ressourcen sorgfältig durch unten, und befolgen Sie die Anweisungen. Ich habe diese Methode nicht persönlich überprüft, aber vielleicht passt sie Ihnen besser als meine "procedure-view"-Lösung.