SQL Frage (Pivot)

diego_armando

Banned
Registriert
Feb. 2015
Beiträge
913
Hi,

ich würde gerne Zeilen in Spalten umwandeln. Aber so ganz hab ich die Pivot-Funktion (Oracle SQL) nicht verstanden. Wenn das so überhaupt klappt. Folgende Ausgangssituation als Beispiel:

TypUhrzeitInfo
A
01.02.2005​
das
A
05.08.2010​
ist
A
01.02.2019​
ein
B
02.08.2014​
test
B
03.05.2015​
das


Als Ergebnis sollte folgendes rauskommen:

TYPUhrzeit1Uhrzeit2Uhrzeit3Info1Info2Info3
A
01.02.2005​
05.08.2010​
01.02.2019​
dasistein
B
02.08.2014​
03.05.2015​
testdas


Könnt ihr mir hier helfen?
Danke!
 
Zunächst: Pivot in Oracle ist statisch, außer Du verwendest XML. Normal muß man die Zielspalten benennen können.

Entsprechend wird Dein Anliegen so erstmal nicht funktionieren.
Mit der Spalte Info funktioniert es dann, wenn dort nur bekannte Werte angenommen werden können.
Mit der Spalte Uhrzeit funktioniert es dann, wenn Du Eingangswerte auf eine geschlossene Menge abbilden kannst, zb per Group By und dann nur Monat und/oder Tag.

Wenn das gegeben ist, machst du:

1. eine normale Abfrage.
2. schreibst Pivot.
3. überlegst dir, wie Felder transformiert werden sollen. Count, min/Max und sowas sind da Kandidaten.
4. jetzt mußt du nach Schema F sagen, welche Werte wo zugeordnet werden sollen. Von der Sache her ist das dasselbe wie ein select case: wenn Wert1 hierhin, wenn Wert2 dorthin usw.

Beispiel:
SQL:
Select Typ, info from src
Pivot
(Count(Typ) as wort_ for(Info) in(
‚das‘ as das,
‚ist‘ as ist,
‚ein‘ as ein,
‚test‘ as Test
) - - in...
) - - pivot

Das liefert die Vorkommen der vier Begriffe das, ist, ein und Test aufgeschlüsselt in die Spalten Wort_das, wort_ist, wort_ein und wort_test, zugeordnet zu ihrem Typ.

Das könnte so zb auf einer Assoziationstabelle für m : n laufen.

Was NICHT ohne XML geht sind Subselects in der Pivotklausel. Man muß tatsächlich sagen, was man will, und dieses Was steht in den Daten. Wenn unbekannte Daten eingetragen werden können geht es schief.
 
Ok, dann klappt es mit Pivot nicht. Es kann immer ein andere text oder auch ein anderes datum vorhanden sein. Wie könnte ich das sonst hinbekommen?
 
Wenn die Anzahl der Spalten fix ist, dann ginge das über Subselects oder Left Joins. Notwendig wäre dabei, dass die Tabelle zusätzlich zu den aufgeführten Spalten eine eindeutige Spalte (ID) besitzt.

Wenn die Anzahl der Spalten variabel sein soll, dann braucht es vermutlich eine Stored Procedure.
 
Spalten sind immer fix,ja. Es gibt leider nichts unique in einer spalte. Typ „A“ kommt öfters vor. Ich müsste wohl eine eigene Id machen.

Dann hätte ich mal das. Wie würde das über Left Joins gehen?

IDTypUhrzeitInfo
1​
A01.02.2005das
2​
A05.08.2010ist
3​
A01.02.2019ein
4​
B02.08.2014test
5​
B03.05.2015das
 
Zuletzt bearbeitet:
Wenn ich das richtig deute ist das doch einfach

1 das Funktional Datum(Typ)
2 das Funktional Info(Typ)

Da kann man prinzipiell zwei Abfragen laufen lassen, durchaus auch in einem Rutsch, wo man 1 und 2 ermittelt und die Ausgabe nebeneinander schreibt. Geht prinzipiell auch per Group by, um eine aggregierte Zuordnung von eindeutigen Typ-Werten auf jeweils die Mengen von Datum und Info zu erhalten.

Muß allerdings nachhelfen und in irgendeiner Form die Anzahl der längsten Liste ermitteln für die Aufteilung der Ergebniszellen.
 
Das Problem dabei ist aber, dass es pro Typ auch 10 Datumszeilen geben kann. Oder auch 20 Info-Zeilen pro Typ. Dann brauchts auf einmal 20 Spalten. Also ich hab mich oben wohl falsch ausgedrückt. Im Ergebnis sollen soviele Spalten angezeigt werden, so oft etwas vom Typ (z.B. A) in der Datums oder Info-Spalte drinsteht.
Wenn alles immer gleich wäre, hätt ichs schon irgendwie gelöst, steh aber grad am Schlauch.

Also ich glaube nicht, dass es so easy ist. Vermutlich wird man um einen Cursor (?) nicht herumkommen, aber da kenn ich mich nicht aus.
 
Was du willst ist ein recursive CTE, ka ob Oracle das unterstützt. Lies dich mal in die Idee dahinter ein. Fall es sich nicht geht, könntest Du es mit einem Cursor auch schaffen, ist halt langsam.

Pivot wird so nicht gehen, da es ein definiertes RecordSet erwartet. Wenn also N eine bekannte Menge ist, kann man das so verwenden.
 
diego_armando schrieb:
Das Problem dabei ist aber, dass es pro Typ auch 10 Datumszeilen geben kann. Oder auch 20 Info-Zeilen pro Typ. Dann brauchts auf einmal 20 Spalten.
Das hatte ich gefragt ^^

Wie ich schon geschrieben habe - am einfachsten geht das mit einer Stored Procedure. Als erstes machst Du in der Stored Procedure eine Abfrage, wieviele Spalten es werden und anschließend baust Du ein Select mit der entsprechenden Anzahl an Spalten ... das nennt sich dynamisches SQL.

Allerdings stellt sich die Frage inwieweit so ein Ergebnis bei 20 Spalten Sinn macht. Ich stelle mir das ziemlich unübersichtlich vor.
 
OK, danke. Prozeduren habe ich schon ein paar gemacht, allerdings weiß ich grad nicht wie ich da hier anfangen soll ("Abfrage machen, wieviele Spalten es werden"). -> das weiß ich nicht, da es bei der nächsten Tabelle dann auch 35 sein können. naja, danke mal.
 
Was ist denn das Ziel des ganzen? Ich halte das von dir gewünschte Ergebnis aktuell für unnötig kompliziert. Es gibt wahrscheinlich eine viel einfachere Lösung, nur dazu müsste man mal wissen, was das Ziel der Auswertung sein soll.
 
Abgesehen davon sollte man Tabelle eher länger als breiter halten um etwaige Probleme mit Buffern vorzubeugen. Bevor ich also anfange mit 30x ein Zeitstempel in eine Zeile zu einer ID wegzuschreiben, würde ich das ganze in die Länge ziehen und die Relation dazu abspeichern.

Wie aber @ayngush schon sagt, ohne das genaue Ziel zu erkennen sind gezielte Hilfestellungen schwierig.
 
diego_armando schrieb:
OK, danke. Prozeduren habe ich schon ein paar gemacht, allerdings weiß ich grad nicht wie ich da hier anfangen soll ("Abfrage machen, wieviele Spalten es werden").
Du selektierst den Wert von "Typ", der am häufigsten vorkommt. Damit hast Du Deine Anzahl der Spalten. Man kann innerhalb einer stored Procedure sowohl Schleifen als auch Stringoperationen benutzen. Du kannst also in einer Schleife 1..Anzahl den SQL-String zusammen bauen und ihn anschließend als select ausführen.

Aber wie schon angemerkt - derartige Spaltenanzahlen machen in der Regel keinen Sinn, weil man die Werte daraus nicht vernünftig weiter verarbeiten kann. Spätestens bei 1000 Spalten ist bei Oracle eh Schluss ...
 
Zuletzt bearbeitet:
Eigentlich bei jeder SQL-DB wird von "table_columns" gesprochen. Die naheliegende Übersetzung ist "Tabellenspalten".
 
  • Gefällt mir
Reaktionen: AgiOli
Zurück
Oben