Direkt zum Hauptinhalt

SQL-Pivotierung: Konvertieren von Zeilen in Spalten

SQL Pivot: Converting Rows to Columns

Veröffentlicht: 1. November 2018

Open-Source6 min Lesezeit

Probieren Sie dieses Notebook in Databricks aus

Sehen Sie sich das E-Book Warum das Data Lakehouse Ihr nächstes Data Warehouse ist an, um die Funktionsweise der Databricks Lakehouse Platform kennenzulernen.

AKTUALISIERT AM 10.11.2018

Pivot wurde erstmals in Apache Spark 1.6 als neue DataFrame-Funktion eingeführt, die es Benutzern ermöglicht, einen Tabellenausdruck zu drehen, indem die eindeutigen Werte aus einer Spalte in einzelne Spalten umgewandelt werden.

Die Version Apache Spark 2.4 erweitert diese leistungsstarke Funktionalität der Datendrehung auch auf unsere SQL-Benutzer. In diesem Blog zeigen wir anhand von Temperaturaufzeichnungen in Seattle, wie wir diese gängige SQL-Pivot-Funktion verwenden können, um komplexe Datentransformationen zu erzielen.

Untersuchung der Sommertemperaturen mit Pivot

In diesem Sommer stiegen die Temperaturen in Seattle auf unangenehme Werte und erreichten an neun Tagen im Juli Höchstwerte von über 26 bis 32 Grad Celsius.

Datum Temperatur (°F)
07-22-2018 86
07-23-2018 90
07-24-2018 91
07-25-2018 92
07-26-2018 92
07-27-2018 88
07-28-2018 85
07-29-2018 94
07-30-2018 89

Angenommen, wir möchten untersuchen, ob es einen historischen Trend bei steigenden Quecksilberwerten gab. Eine intuitive Möglichkeit, diese Zahlen zu untersuchen und darzustellen, besteht darin, die Monate als Spalten und dann die monatlichen Durchschnittswerte jedes Jahres in einer einzigen Zeile darzustellen. Auf diese Weise ist es einfach, die Temperaturen sowohl horizontal, zwischen benachbarten Monaten, als auch vertikal, zwischen verschiedenen Jahren, zu vergleichen.

Nachdem wir nun die PIVOT-Syntax in Spark SQL unterstützen, können wir dies mit der folgenden SQL-Abfrage erreichen.

Die obige Abfrage erzeugt ein Ergebnis wie folgt:

JAHR JAN FEB MÄR APR MAI JUNI JULI AUG SEPT OKT NOV DEZ
2018 49.7 45.8 54.0 58.6 70.8 71.9 82.8 79.1 NULL NULL NULL NULL
2017 43.7 46.6 51.6 57.3 67.0 72.1 78.3 81.5 73.8 61.1 51.3 45.6
2016 49.1 53.6 56.4 65.9 68.8 73.1 76.0 79.5 69.6 60.6 56.0 41.9
2015 50.3 54.5 57.9 59.9 68.0 78.9 82.6 79.0 68.5 63.6 49.4 47.1

Nun, es sieht so aus, als gäbe es gute und schlechte Jahre. Das Jahr 2016 scheint ein eher energiesparendes Jahr zu sein.

Pivotieren in SQL

Werfen wir einen genaueren Blick auf diese Abfrage, um zu verstehen, wie sie funktioniert. Zuerst müssen wir die FROM-Klausel angeben, die die Eingabe des Pivots ist, mit anderen Worten, die Tabelle oder Unterabfrage, auf der die Pivotierung durchgeführt wird. In unserem Fall interessieren wir uns für die Jahre, die Monate und die hohen Temperaturen, also sind dies die Felder, die in der Unterabfrage erscheinen.

Zweitens betrachten wir einen weiteren wichtigen Teil der Abfrage, die PIVOT-Klausel. Das erste Argument der PIVOT-Klausel ist eine Aggregatfunktion und die zu aggregierende Spalte. Anschließend geben wir die Pivotspalte in der FOR-Unterklausel als zweites Argument an, gefolgt vom Operator IN, der die Pivotspaltenwerte als letztes Argument enthält.

Die Pivotspalte ist der Punkt, um den die Tabelle gedreht wird, und die Pivotspaltenwerte werden in Spalten in der Ausgabetabelle transponiert. Mit der IN-Klausel können Sie auch einen Alias für jeden Pivotwert angeben, wodurch es einfach ist, aussagekräftigere Spaltennamen zu generieren.

Eine wichtige Idee bei Pivot ist, dass es eine gruppierte Aggregation basierend auf einer Liste von impliziten group-by-Spalten zusammen mit der Pivotspalte durchführt. Die impliziten group-by-Spalten sind Spalten aus der FROM-Klausel, die in keiner Aggregatfunktion oder als Pivotspalte vorkommen.

In der obigen Abfrage, wobei die Pivotspalte die Spalte month und die implizite group-by-Spalte die Spalte year ist, wird der Ausdruck avg(temp) für jedes eindeutige Wertepaar von (year, month) aggregiert, wobei month einem der angegebenen Pivotspaltenwerte entspricht. Infolgedessen wird jeder dieser aggregierten Werte seiner entsprechenden Zelle der Zeile year und der column month zugeordnet.

Es ist erwähnenswert, dass wir aufgrund dieser impliziten group-by sicherstellen müssen, dass jede Spalte, die nicht Teil der Pivot-Ausgabe sein soll, aus der FROM-Klausel entfernt wird, da die Abfrage sonst unerwünschte Ergebnisse liefern würde.

E-Book

Erste Schritte mit ETL

Angeben mehrerer Aggregatausdrücke

Das obige Beispiel zeigt nur einen Aggregatausdruck, der in der PIVOT-Klausel verwendet wird, während Benutzer bei Bedarf tatsächlich mehrere Aggregatausdrücke angeben können. Auch hier können wir mit den obigen Wetterdaten die maximalen Höchsttemperaturen zusammen mit den durchschnittlichen Höchsttemperaturen zwischen Juni und September auflisten.

Im Fall von mehreren Aggregatausdrücken sind die Spalten das kartesische Produkt der Pivotspaltenwerte und der Aggregatausdrücke, wobei die Namen _ lauten.

year JUN_avg JUN_max JUL_avg JUL_max AUG_avg AUG_max SEP_avg SEP_max
2018 71.9 88 82.8 94 79.1 94 NULL NULL
2017 72.1 96 78.3 87 81.5 94 73.8 90
2016 73.1 93 76.0 89 79.5 95 69.6 78
2015 78.9 92 82.6 95 79.0 92 68.5 81

Gruppierungsspalten vs. Pivotspalten

Nehmen wir nun an, wir möchten die niedrigen Temperaturen in unsere Untersuchung der Temperaturtrends aus dieser Tabelle der täglichen niedrigen Temperaturen einbeziehen:

Datum Temperatur (°F)
... ...
08-01-2018 59
08-02-2018 58
08-03-2018 59
08-04-2018 58
08-05-2018 59
08-06-2018 59
... ...

Um diese Tabelle mit der vorherigen Tabelle der täglichen Höchsttemperaturen zu kombinieren, könnten wir diese beiden Tabellen über die Spalte „Datum“ verknüpfen. Da wir jedoch Pivot verwenden werden, das eine Gruppierung nach Datum durchführt, können wir die beiden Tabellen einfach mit UNION ALL verketten. Und Sie werden später sehen, dass dieser Ansatz uns auch mehr Flexibilität bietet:

Versuchen wir nun unsere Pivot-Abfrage mit der neuen kombinierten Tabelle:

Als Ergebnis erhalten wir die durchschnittlichen Höchst- und Tiefstwerte für jeden Monat der letzten 4 Jahre in einer Tabelle. Beachten Sie, dass wir die Spalte flag in die Pivot-Abfrage aufnehmen müssen, da der Ausdruck avg(temp) sonst auf einer Mischung aus hohen und niedrigen Temperaturen basieren würde.

year H/L JUN JUL AUG SEP
2018 H 71.9 82.8 79.1 NULL
2018 L 53.4 58.5 58.5 NULL
2017 H 72.1 78.3 81.5 73.8
2017 L 53.7 56.3 59.0 55.6
2016 H 73.1 76.0 79.5 69.9
2016 L 53.9 57.6 59.9 52.9
2015 H 78.9 82.6 79.0 68.5
2015 L 56.4 59.9 58.5 52.5

Sie haben vielleicht bemerkt, dass wir jetzt zwei Zeilen für jedes Jahr haben, eine für die hohen Temperaturen und die andere für die niedrigen Temperaturen. Das liegt daran, dass wir eine weitere Spalte, flag, in die Pivot-Eingabe aufgenommen haben, die wiederum zu einer weiteren impliziten Gruppierungsspalte zusätzlich zur ursprünglichen Spalte year wird.

Alternativ kann die flag, anstatt eine Gruppierungsspalte zu sein, auch als Pivotspalte dienen. Wir haben also jetzt zwei Pivotspalten, month und flag:

Diese Abfrage präsentiert uns ein anderes Layout derselben Daten, mit einer Zeile für jedes Jahr, aber zwei Spalten für jeden Monat.

year JUN_hi JUN_lo JUL_hi JUL_lo AUG_hi AUG_lo SEP_hi SEP_lo
2018 71.9 53.4 82.8 58.5 79.1 58.5 NULL NULL
2017 72.1 53.7 78.3 56.3 81.5 59.0 73.8 55.6
2016 73.1 53.9 76.0 57.6 79.5 57.9 69.6 52.9
2015 78.9 56.4 82.6 59.9 79.0 58.5 68.5 52.5

Wie geht es weiter?

Um die in diesem Blog verwendeten Abfragebeispiele auszuführen, überprüfen Sie bitte die Pivot-SQL-Beispiele in diesem begleitenden Notebook.

Vielen Dank an die Mitwirkenden der Apache Spark-Community für ihre Beiträge!

(Dieser Blogbeitrag wurde mit KI-gestützten Tools übersetzt.) Originalbeitrag

Verpassen Sie keinen Beitrag von Databricks

Abonnieren Sie unseren Blog und erhalten Sie die neuesten Beiträge direkt in Ihren Posteingang.