Es gibt verschiedene Möglichkeiten, wie Sie diese Datenumwandlung durchführen können. Sie haben Zugriff auf die PIVOT
Funktion, dann ist dies die einfachste. Wenn nicht, können Sie eine Aggregatfunktion und eine verwenden CASE
.
Aggregat / Fallversion:
select personid,
max(case when optionid = 'A' then 1 else 0 end) OptionA,
max(case when optionid = 'B' then 1 else 0 end) OptionB,
max(case when optionid = 'C' then 1 else 0 end) OptionC
from PersonOptions
group by personid
order by personid;
Siehe SQL Fiddle with Demo
Statischer Drehpunkt:
select *
from
(
select personid, optionid
from PersonOptions
) src
pivot
(
count(optionid)
for optionid in ('A' as OptionA, 'B' OptionB, 'C' OptionC)
) piv
order by personid
Siehe SQL Fiddle with Demo
Dynamische Version:
Die beiden obigen Versionen funktionieren hervorragend, wenn Sie eine bekannte Anzahl von Werten haben, aber wenn Ihre Werte unbekannt sind, möchten Sie dynamisches SQL implementieren und in Oracle können Sie eine Prozedur verwenden:
CREATE OR REPLACE procedure dynamic_pivot_po(p_cursor in out sys_refcursor)
as
sql_query varchar2(1000) := 'select personid ';
begin
for x in (select distinct OptionID from PersonOptions order by 1)
loop
sql_query := sql_query ||
' , min(case when OptionID = '''||x.OptionID||''' then 1 else null end) as Option_'||x.OptionID;
dbms_output.put_line(sql_query);
end loop;
sql_query := sql_query || ' from PersonOptions group by personid order by personid';
dbms_output.put_line(sql_query);
open p_cursor for sql_query;
end;
/
Dann geben Sie die Ergebnisse zurück und verwenden:
variable x refcursor
exec dynamic_pivot_po(:x)
print x
Die Ergebnisse sind bei allen Versionen gleich:
| PERSONID | OPTIONA | OPTIONB | OPTIONC |
------------------------------------------
| 1 | 1 | 1 | 0 |
| 2 | 0 | 0 | 1 |
| 3 | 0 | 1 | 0 |
| 4 | 1 | 0 | 1 |
where a.personId = a2.personId order by a2.personId for xml path('')
. a2 ist die Tabelle in der Unterabfrage. Dann trenne ich die Daten in Excel mithilfe von Text in Spalten mit Komma als Trennzeichen. Ich hatte gehofft, einen Weg zu finden, dies in regulärem SQL zu tun, ohne eine Prozedur schreiben zu müssen, aber vielleicht gibt es keinen Weg. Müssen im Moment laufen, aber ich werde versuchen, ein Beispiel dafür zu posten, um es besser zu erklären.Dies entspricht der SQL Server-Syntax. Aufgrund meiner Lektüre der Oracle-Dokumente scheinen NULLIF und PIVOT dasselbe Format zu haben wie ihre SQL Server-Verwandten. Die Herausforderung wird die Pivot-Liste sein, die statisch sein muss, es sei denn, Sie machen die Abfrage dynamisch, wie Itzik demonstriert, aber ich habe keine Ahnung, ob das in P / SQL übersetzt werden kann
quelle
Ich bevorzuge die manuelle Pivot-Abfrage, aber Sie können auch verwenden
PIVOT
.quelle
PIVOT
Syntax im Vergleich zu meinem Ansatz komplizierter ist. Ich bin mir jedoch bewusst, dass beide das gleiche Ergebnis liefern, und ich bin mir einig, dass andere Leute möglicherweise gegenteilig denken.