14th May 2024 17 Leseminuten GROUP BY und Aggregatfunktionen: Ein vollständiger Überblick Tihomir Babic Aggregatfunktionen GROUP BY Inhaltsverzeichnis Die Grundsyntax von GROUP BY mit Aggregaten SQL-Aggregatfunktionen Verwendung von GROUP BY mit SQL-Aggregatfunktionen Beispiel 1: COUNT() mit GROUP BY Beispiel 2: SUMME() mit GROUP BY Beispiel 3: AVG() mit GROUP BY Beispiel 4: MIN() und MAX() mit GROUP BY Fortgeschrittene GROUP BY-Techniken Aggregierte Ergebnisse mit HAVING filtern Gruppieren nach mehreren Spalten Beispiel Zwei Aggregatfunktionen in einer Abfrage Eine Abfrage, zwei Aggregatfunktionen: Der einfache Ansatz Beispiel Eine Abfrage, zwei Aggregatfunktionen: Der fortgeschrittene Ansatz Beispiel GROUP BY mit bedingten Aggregaten Beispiel GROUP BY-Erweiterungen: ROLLUP, CUBE, GRUPPIERUNGSSÄTZE Beispiel Häufige Fehler bei der Verwendung von GROUP BY Verwechslung von ORDER BY und GROUP BY WHERE und HAVING verwechseln Beispiel Auflistung nicht aggregierter Spalten in SELECT, aber nicht in WHERE Beispiel Andere Fehler Weitere SQL GROUP BY Ressourcen Die SQL-Funktionen GROUP BY und Aggregat sind für die Aggregation von Daten sowie für die Analyse von Daten und die Erstellung von Berichten unerlässlich. Lassen Sie uns diese Funktionen gemeinsam erkunden! In SQL sind GROUP BY und Aggregatfunktionen eine der beliebtesten Funktionen der Sprache. Die Datenaggregation ist für die Datenanalyse und die Erstellung von Berichten von entscheidender Bedeutung; um alle Daten in einem Datensatz sinnvoll nutzen zu können, müssen sie oft aggregiert werden. Aber was ist Datenaggregation? Einfach ausgedrückt: Sie gruppieren Daten auf der Grundlage gemeinsamer Werte und führen für jede Datengruppe eine Berechnung durch. Sie könnten zum Beispiel eine Liste von Hunden nach ihrer Rasse gruppieren und dann eine Berechnung durchführen, um die durchschnittliche Größe für jede Rasse zu ermitteln. Diese Aufgabe wird durch die GROUP BY-Klausel und die Aggregatfunktion AVG() ermöglicht. Wenn Sie Ihr Wissen über GROUP BY auffrischen möchten, ist unser SQL für Anfänger Kurs ideal. Er enthält 129 interaktive Übungen, die Sie in etwa 10 Stunden absolvieren können. Er behandelt Themen wie das Filtern von Daten, die Verwendung logischer Operatoren, die Verknüpfung und die Verwendung von Mengenoperatoren. Die Grundsyntax von GROUP BY mit Aggregaten GROUP BY ist eine Klausel in SQL, die Daten mit gleichen Werten in Gruppen zusammenfasst. Die Gruppierung erfolgt nach Spalte(n), wobei alle Zeilen mit demselben Wert in dieser Spalte zu einer Gruppe gehören. Sie können dann für jede Gruppe zusammenfassende Berechnungen durchführen, z. B. Zählung, Summierung oder Mittelwertbildung von Werten. Mit GROUP BY können Sie zum Beispiel die Anzahl der Mitarbeiter in einer Abteilung, das Gesamtgehalt oder das Durchschnittsgehalt pro Abteilung usw. berechnen. Die Syntax von GROUP BY mit einer Aggregatfunktion lautet: SELECT column1, column2, ..., aggregate_function(column_name) FROM table_name WHERE filtering_condition GROUP BY column1, column2, … HAVING filtering_condition; Die Aggregatfunktion wird in die Anweisung SELECT geschrieben, und das Ergebnis der Funktion wird als zusätzliche Spalte angezeigt. Die Klausel GROUP BY enthält die Spalten, nach denen Ihre Ausgabe gruppiert werden soll. Diese Klausel wird häufig zusammen mit den Klauseln WHERE und HAVING zur Filterung verwendet. In der Syntax steht WHERE vor GROUP BY, während HAVING danach kommt. (Ich werde später mehr über diese beiden Klauseln erklären.) Außerdem werden Ihre Daten manchmal NULLs enthalten, so dass es für Sie interessant sein wird zu erfahren , wie GROUP BY mit NULLs umgeht. Ein Beispiel für GROUP BY in Aktion ist im folgenden GIF zu sehen. In diesem einfachen Beispiel werden die Daten nach Regisseuren gruppiert und die Anzahl der Filme angezeigt, die jeder von ihnen gemacht hat. SQL-Aggregatfunktionen Die Aggregatfunktionen von SQL werden verwendet, wenn Sie Berechnungen mit Daten durchführen und einen einzigen Wert zurückgeben möchten. Die gebräuchlichsten Aggregatfunktionen in SQL sind: COUNT() - Zählt die Zeilen in der angegebenen Spalte. SUM() - Gibt die Summe aller Werte zurück. AVG() - Berechnet den Durchschnitt einer Gruppe von Werten. MIN() - Gibt das Minimum (den niedrigsten Wert) der angegebenen Werte zurück. MAX() - Gibt das Maximum (den höchsten Wert) der angegebenen Werte zurück. In unseren Anleitungen erfahren Sie, wie Sie diese Funktionen verwenden, um Aggregate für die gesamte Tabelle zu berechnen: Wie man die Anzahl der Zeilen in einer Tabelle in SQL zählt Zählen von eindeutigen Werten in SQL Wie addiert man Werte einer Spalte in SQL? Wie findet man den Durchschnitt einer numerischen Spalte in SQL? Wie ermittle ich den Maximalwert einer Spalte in SQL? Wie finde ich den Mindestwert einer Spalte in SQL? Es ist wichtig zu beachten, dass die Funktion COUNT() mehrere verschiedene Verwendungsvarianten hat: COUNT(*) Zählt alle Zeilen in einer Ergebnismenge, einschließlich NULL-Werte und Duplikate. COUNT(expression) Zählt die Nicht-NULL-Werte in einer Ergebnismenge. COUNT(DISTINCT) Zählt eindeutige Werte und ignoriert Duplikate. Weitere Details finden Sie in unserem Leitfaden Was ist der Unterschied zwischen COUNT(*), COUNT(1), COUNT(column) und COUNT(DISTINCT)? Verwendung von GROUP BY mit SQL-Aggregatfunktionen Ich verwende die Tabelle albums um zu zeigen, wie Aggregatfunktionen und GROUP BY zusammenarbeiten. Das Skript zum Erstellen der Tabelle finden Sie hier. Diese Tabelle enthält Daten über Musikalben. Hier ist ein Schnappschuss: idartistalbumrelease_yearlengthlabel 1Grant GreenThe Latin Bit19630:38:56Blue Note Records 2AC/DCHigh Voltage19760:44:23Atlantic Records 3Brother Jack McDuffTo Seek a New Home19700:33:12Blue Note Records 4Grant GreenGreen Is Beautiful19700:37:33Blue Note Records 5Wayne ShorterMoto Grosso Feio19740:42:22Blue Note Records Beispiel 1: COUNT() mit GROUP BY Hier ist ein Beispielcode, der die Anzahl der Alben nach Label zählt: SELECT label, COUNT(*) AS number_of_albums FROM albums GROUP BY label; Ich wähle das Label aus und verwende COUNT(*), um die Anzahl der Alben zu ermitteln. Das Sternchen (*) ist eine Abkürzung für das Zählen aller Zeilen. Wenn ich die Ausgabe nach Label gruppiere, zeigt COUNT() die Anzahl der Alben pro Label an. Hier ist die Ausgabe: labelnumber_of_albums Atlantic Records13 Blue Note Records12 Stax Records14 Weitere Lektüre: Eine ausführliche Anleitung zur SQL-Funktion COUNT(). Die SQL-Funktion Count wird anhand von 7 Beispielen erklärt. Wie man die Anzahl der Zeilen in einer Tabelle in SQL zählt. Was ist der Unterschied zwischen COUNT(*), COUNT(1), COUNT(column), und COUNT(DISTINCT). Wie zählt man eindeutige Werte in SQL. Beispiel 2: SUMME() mit GROUP BY Der folgende Code summiert die Albumlängen, um die gesamte verfügbare Musik pro Künstler anzuzeigen: SELECT artist, SUM(length) AS total_music_available FROM albums GROUP BY artist; Die Funktion SUM() wird auf die Spalte length angewendet, und die Ausgabe wird dann nach dem Künstler gruppiert. Dies ist das Ergebnis des Codes: artisttotal_music_available Isaac Hayes6:30:02 Otis Redding1:34:09 Brother Jack McDuff1:58:11 Aretha Franklin1:47:07 Grant Green3:10:11 John Prine1:21:57 Led Zeppelin3:32:07 Wayne Shorter2:38:02 Albert King3:08:28 AC/DC2:05:23 Weitere Lektüre: SQL SUM() Funktion erklärt mit 5 praktischen Beispielen. Wie man die Werte einer Spalte in SQL summiert. Beispiel 3: AVG() mit GROUP BY Dieser Code berechnet die durchschnittliche Albumlänge der einzelnen Künstler: SELECT artist, AVG(length) AS average_album_length FROM albums GROUP BY artist; Um das gewünschte Ergebnis zu erhalten, müssen Sie AVG() auf die Spalte length anwenden und die Ausgabe nach artist gruppieren. So sieht die Ausgabe aus: artistaverage_album_length Isaac Hayes1:05:00 Otis Redding0:31:23 Brother Jack McDuff0:39:24 Aretha Franklin0:35:42 Grant Green0:38:02 John Prine0:40:59 Led Zeppelin0:42:25 Wayne Shorter0:39:31 Albert King0:37:42 AC/DC0:41:48 Weitere Lektüre: Die SQL-Funktion AVG() erklärt mit Beispielen Wie man den Durchschnitt einer numerischen Spalte in SQL ermittelt Beispiel 4: MIN() und MAX() mit GROUP BY Lassen Sie uns die kürzeste und die längste Albumlänge für jedes Jahr ermitteln: SELECT release_year, MIN(length) AS minimum_album_length, MAX(length) AS maximum_album_length FROM albums GROUP BY release_year ORDER BY release_year; Wie in früheren Beispielen werden die Aggregatfunktionen auf die Spalte length angewendet; MIN() für das kürzeste und MAX() für das längste Album. Die Ausgabe ist nach Erscheinungsjahr gruppiert. Ich habe außerdem die Klausel ORDER BY hinzugefügt, um die Ausgabe vom frühesten bis zum neuesten Jahr zu sortieren, damit sie besser lesbar ist. Hier ist die Code-Ausgabe: release_yearminimum_album_lengthmaximum_album_length 19620:34:490:34:49 19630:38:560:38:56 19640:30:170:30:17 19650:32:220:42:45 19670:32:510:41:08 19680:29:300:29:30 19690:31:300:46:00 19700:33:120:43:04 19710:42:371:33:38 19720:37:500:44:46 19730:40:571:43:10 19740:42:220:46:00 19760:39:590:44:23 19770:41:010:41:01 Weitere Lektüre: SQL MIN und MAX Funktionen in 6 Beispielen erklärt Wie findet man den Maximalwert einer numerischen Spalte in SQL? Wie findet man den Mindestwert einer Spalte in SQL? Fortgeschrittene GROUP BY-Techniken Im vorherigen Abschnitt wurden die Grundlagen der Verwendung von SQL-Aggregatfunktionen und GROUP BY behandelt. Mit diesen Grundlagen können wir nun einige fortgeschrittene GROUP BY Techniken untersuchen. Aggregierte Ergebnisse mit HAVING filtern Um aggregierte Ergebnisse zu filtern, müssen Sie die HAVING Klausel verwenden. Ihre Syntax ist hier dargestellt: SELECT column1, column2, ..., aggregate_function(column_name) FROM table_name GROUP BY column1, column2, … HAVING filtering_condition; HAVING HAVING vergleicht die aggregierten Werte mit der Filterbedingung und gibt nur die Werte zurück, die diese Bedingung erfüllen. Mehr dazu erfahren Sie in unserem Artikel über die HAVING-Klausel. Ich möchte Ihnen ein Beispiel zeigen. Der folgende Code berechnet die durchschnittliche Albumlänge pro Künstler, zeigt aber nur diejenigen an, deren durchschnittliche Albumlänge unter 40 Minuten liegt. SELECT artist, AVG(length) AS average_album_length FROM albums GROUP BY artist HAVING AVG(length) < '00:40:00'; Ich habe die Funktion AVG() verwendet, wie ich es zuvor getan habe. Die Klausel HAVING ist neu. Um die Daten auf die gewünschte Weise zu filtern, habe ich in HAVING die gleiche Durchschnittsberechnung wie in SELECT geschrieben. Dann verwende ich den Vergleichsoperator "kleiner als" (<), um jedes gruppierte Ergebnis mit einem Wert zu vergleichen (in diesem Fall 40 Minuten). Dieser Wert wird in einfache Anführungszeichen gesetzt (''). Der Wert in den Anführungszeichen muss im Format HH:MM:SS (Stunden:Minuten:Sekunden) geschrieben werden, da die Werte in der Spalte length vom Datentyp INTERVAL sind. Hier ist die Ausgabe: artistaverage_album_length Otis Redding0:31:23 Brother Jack McDuff0:39:24 Aretha Franklin0:35:42 Grant Green0:38:02 Wayne Shorter0:39:31 Albert King0:37:42 Das Prinzip ist das gleiche, egal welche Aggregatfunktion Sie verwenden, aber hier sind die Kochbücher, die Ihnen mit einigen anderen Funktionen helfen: Filtern von Datensätzen mit der Aggregatfunktion COUNT Filtern von Datensätzen mit der Aggregatfunktion SUM Filtern von Datensätzen mit der Aggregatfunktion AVG Gruppieren nach mehreren Spalten Bislang habe ich Daten nach einer Spalte gruppiert. Es ist jedoch auch möglich, nach zwei oder mehr Spalten zu gruppieren. Das ist nicht kompliziert: Sie müssen nur alle Gruppierungsspalten in GROUP BY auflisten und sie durch Kommas trennen. Auf diese Weise gruppieren Sie nicht nur nach den Spaltenwerten, sondern auch nach der Kombination von Werten in allen Gruppierungsspalten. Wenn Sie den Wert A in Spalte_1 und den Wert B in Spalte_2 haben, ist dies eine Gruppe. Gibt es z. B. in Spalte_1 den Wert A und in Spalte_2 den Wert C, so bildet dies eine weitere Gruppe - obwohl die Werte in Spalte_1 dieselben sind wie im vorherigen Beispiel. Beispiel Der folgende Code zeigt die Anzahl der Alben des Künstlers und das Jahr der Veröffentlichung an: SELECT artist, release_year, COUNT(*) AS number_of_albums FROM albums GROUP BY artist, release_year ORDER BY artist, release_year; Ich verwende COUNT(*), um die Anzahl der Alben zu ermitteln. Die Ausgabe ist nach Künstler und Erscheinungsjahr gruppiert. Wie Sie sehen können, sind dies genau die Spalten in GROUP BY und sie sind durch ein Komma getrennt. Um die Ausgabe besser lesbar zu machen, habe ich die Daten nach Künstler alphabetisch und vom frühesten bis zum spätesten Erscheinungsjahr sortiert. Dies ist der Schnappschuss der Ausgabe: artistrelease_yearnumber_of_albums AC/DC19762 AC/DC19771 Albert King19621 Albert King19671 Albert King19691 Albert King19721 Albert King19741 Aretha Franklin19671 Aretha Franklin19681 Aretha Franklin19721 Brother Jack McDuff19692 Brother Jack McDuff19701 Zwei Aggregatfunktionen in einer Abfrage Es ist auch möglich, eine Abfrage zu schreiben, die zwei Aggregatfunktionen enthält. Nein, es ist nicht so, wie Sie denken: Sie schreiben nicht eine Aggregatfunktion innerhalb einer anderen. Das ist in SQL nicht möglich. Zwei Aggregatfunktionen in einer Abfrage können zwei Dinge bedeuten: Einfacher Ansatz: Verwendung von zwei Aggregatfunktionen in zwei Spalten der gleichen SELECT. Fortgeschrittener Ansatz: Verwendung des Ergebnisses einer Aggregatfunktion in einer anderen Aggregatfunktion. Eine Abfrage, zwei Aggregatfunktionen: Der einfache Ansatz Der einfache Ansatz besteht also darin, zwei Aggregatfunktionen in zwei verschiedenen Aggregatspalten in einer SELECT zu haben. Dabei kann es sich um dieselbe Funktion handeln, die auf verschiedene Spalten angewendet wird, um verschiedene Funktionen, die auf dieselbe Spalte angewendet werden, oder um verschiedene Funktionen, die auf verschiedene Spalten angewendet werden. Das spielt eigentlich keine Rolle; der Punkt ist, dass Sie zwei Aggregationen in einer Abfrage haben. Diese Aggregationen "kommunizieren" nicht, d.h. sie sind in keiner Weise voneinander abhängig. Beispiel In diesem Beispiel verwende ich die Tabelle package_deliveries mit dem hier verlinkten Skript. Die Tabelle enthält Informationen über die Anzahl der Pakete, die täglich in mehrere Städte geliefert werden. Hier sind die ersten sechs Zeilen der Tabelle: iddate_of_deliverynumber_of_packagescity_of_deliverycountry_of_delivery 12024-03-0149KrakowPoland 22024-03-01528WarsawPoland 32024-03-01158GdanskPoland 42024-03-0128RijekaCroatia 52024-03-0197SplitCroatia 62024-03-0164ZagrebCroatia Der folgende Code berechnet die Gesamtzahl und die durchschnittliche Anzahl der Pakete pro Stadt. SELECT city_of_delivery, SUM(number_of_packages) AS total_number_of_packages, AVG(number_of_packages) AS average_number_of_packages FROM package_deliveries GROUP BY city_of_delivery; Wie Sie sehen, hat die Abfrage zwei Aggregate: eines mit SUM() und eines mit AVG(). Es ist völlig egal, wie viele Aggregatfunktionen Sie in die Abfrage schreiben. Wichtig ist nur, dass jedes Aggregat als eigene Codezeile oder Ausgabespalte behandelt wird. Hier ist das Ergebnis: city_of_deliverytotal_number_of_packagesaverage_number_of_packages Split531177.00 Izmir5,9361,978.67 Ankara9,1393,046.33 Gdansk712237.33 Rijeka627209.00 Zagreb930310.00 Istanbul13,8574,619.00 Krakow673224.33 Warsaw2,358786.00 Eine Abfrage, zwei Aggregatfunktionen: Der fortgeschrittene Ansatz Die fortgeschrittene Version ist die, bei der die Aggregate "kommunizieren", d. h. Sie müssen zunächst einen aggregierten Wert finden und diesen dann zur Berechnung eines anderen aggregierten Wertes verwenden. Dies wird in der Regel entweder durch Unterabfragen oder Common Table Expressions (CTEs) erreicht. Ich zeige Ihnen die Verwendung von Unterabfragen in dem folgenden Beispiel. Unser Leitfaden zur Kombination zweier Aggregatfunktionen in GROUP BY deckt beide Ansätze ab. Beispiel Der folgende Code gibt die durchschnittliche tägliche Anzahl von Paketen zurück, die in jedem Land zugestellt wurden: SELECT country_of_delivery, AVG(pd.daily_number_of_packages) AS average_daily_number_of_packages FROM (SELECT date_of_delivery, country_of_delivery, SUM(number_of_packages) AS daily_number_of_packages FROM package_deliveries GROUP BY date_of_delivery, country_of_delivery) AS pd GROUP BY country_of_delivery; Zunächst muss die Anzahl der täglich in jedem Land zugestellten Pakete ermittelt werden, was die erste Aggregation darstellt. Die zweite Aggregation verwendet dieses Ergebnis und berechnet den Tagesdurchschnitt pro Land. Die erste Aggregation ist in der Subquery enthalten. Sie verwendet die Funktion SUM() und listet die Spalten date_of_delivery und country_of_delivery in SELECT auf. Die Ausgabe wird nach denselben Spalten gruppiert. Jetzt kann ich die Hauptabfrage schreiben, wobei ich in AVG() auf die Spalte daily_number_of_packages aus der Unterabfrage verweise. Ich gruppiere die Ausgabe nach Land und erhalte die durchschnittliche tägliche Anzahl der zugestellten Pakete für jedes Land. country_of_deliveryaverage_daily_number_of_packages Turkey9,644.00 Croatia696.00 Poland1,247.67 GROUP BY mit bedingten Aggregaten Die Anweisung CASE oder CASE WHEN kennzeichnet Daten auf der Grundlage ihrer Werte. Diese Anweisung kann auch mit GROUP BY verwendet werden. Die Gruppierung von Daten durch bedingte Aggregate bedeutet, dass Sie CASE WHEN mit GROUP BY verwenden. Allerdings - und das ist wichtig - muss das CASE WHEN, das Sie in SELECT schreiben, auch in GROUP BY erscheinen. Beispiel Anhand der Tabelle aus dem vorherigen Beispiel kann ich einen Code schreiben, der die Länder in EU- und Nicht-EU-Länder unterteilt und die Gesamtzahl der zugestellten Pakete für jede Kategorie anzeigt: SELECT CASE WHEN country_of_delivery = 'Turkey' THEN 'Non-EU' ELSE 'EU' END, SUM(number_of_packages) AS total_number_of_packages FROM package_deliveries GROUP BY CASE WHEN country_of_delivery = 'Turkey' THEN 'Non-EU' ELSE 'EU' END; Die Anweisung CASE besagt, dass die Türkei als Nicht-EU-Land kategorisiert werden sollte. Diese Bedingung ist in WHEN aufgeführt. Die Kategorie für alle anderen Länder ist EU, die in ELSE angegeben ist. Die Anweisung CASE beginnt mit CASE (daher der Name) und endet mit dem Schlüsselwort END. Ich verwende die Funktion SUM(), um die Gesamtzahl der Pakete zu berechnen. Um diesen Wert nach Kategorie anzuzeigen, habe ich einfach die gesamte Anweisung CASE WHEN in GROUP BY kopiert. Hier ist die Ausgabe: casetotal_number_of_packages Non-EU28,932 EU5,831 Wenn Sie weitere Beispiele benötigen, um dies vollständig zu verstehen, lesen Sie einen unserer Leitfäden: Wie man CASE WHEN mit SUM() in SQL verwendet Wie verwendet man CASE WHEN in GROUP BY GROUP BY-Erweiterungen: ROLLUP, CUBE, GRUPPIERUNGSSÄTZE Die drei SQL GROUP BY Erweiterungen sind: ROLLUP - Erzeugt eine Summenzeile für die in GROUP BY aufgeführten Gruppen. CUBE - Erzeugt Zwischensummen für alle Kombinationen der Gruppen in GROUP BY. GROUPING SETS - Aggregiert die Ausgabe auf mehreren Ebenen. In diesem Beispiel zeige ich Ihnen, wie GROUPING SETS funktioniert. Wie die anderen beiden Erweiterungen funktionieren, erfahren Sie in unserem Handbuch zu den GROUP BY-Erweiterungen. Beispiel Der folgende Code gibt die Anzahl der zugestellten Pakete pro Land und pro Datum aus: SELECT country_of_delivery, date_of_delivery, SUM(number_of_packages) AS total_number_of_packages FROM package_deliveries GROUP BY GROUPING SETS(country_of_delivery, date_of_delivery) ORDER BY country_of_delivery, date_of_delivery; Ich beginne mit SUM(), um die Anzahl der Pakete zu berechnen. In GROUP BY schreibe ich GROUPING SETS mit allen Aggregationsebenen innerhalb der Klammern. Die Ausgabe zeigt die Anzahl der zugestellten Pakete nach Land und nach Zustellungsdatum: country_of_deliverydate_of_deliverytotal_number_of_packages CroatiaNULL2,088 PolandNULL3,743 TurkeyNULL28,932 NULL2024-03-012,730 NULL2024-03-0211,208 NULL2024-03-0320,825 Es kann hilfreich sein, sich die Gruppierungssätze als zwei separate Abfragen vorzustellen. Die erste Abfrage gruppiert nach Land ... SELECT country_of_delivery, NULL AS date_of_delivery, SUM(number_of_packages) AS total_number_of_packages FROM package_deliveries GROUP BY country_of_delivery ORDER BY country_of_delivery; ... und gibt die ersten drei Zeilen der vorherigen Ausgabe zurück: country_of_deliverydate_of_deliverytotal_number_of_packages CroatiaNULL2,088 PolandNULL3,743 TurkeyNULL28,932 Die zweite Abfrage gruppiert nach Lieferdatum ... SELECT NULL AS country_of_delivery, date_of_delivery, SUM(number_of_packages) AS total_number_of_packages FROM package_deliveries GROUP BY date_of_delivery ORDER BY date_of_delivery; ... und gibt die anderen drei Zeilen des ursprünglichen Ergebnisses aus: country_of_deliverydate_of_deliverytotal_number_of_packages NULL2024-03-012,730 NULL2024-03-0211,208 NULL2024-03-0320,825 Mit anderen Worten, wenn Sie diese beiden separaten Gruppierungsabfragen mit UNION zusammenführen ... SELECT country_of_delivery, NULL AS date_of_delivery, SUM(number_of_packages) AS total_number_of_packages FROM package_deliveries GROUP BY country_of_delivery UNION SELECT NULL AS country_of_delivery, date_of_delivery, SUM(number_of_packages) AS total_number_of_packages FROM package_deliveries GROUP BY date_of_delivery ORDER BY country_of_delivery, date_of_delivery; ... erhalten Sie genau das gleiche Ergebnis wie mit GROUPING SETS. country_of_deliverydate_of_deliverytotal_number_of_packages CroatiaNULL2,088 PolandNULL3,743 TurkeyNULL28,932 NULL2024-03-012,730 NULL2024-03-0211,208 NULL2024-03-0320,825 Häufige Fehler bei der Verwendung von GROUP BY Verwechslung von ORDER BY und GROUP BY Dies liegt oft daran, dass man nicht weiß, was GROUP BY tut. Lassen Sie es mich anhand eines Beispiels demonstrieren. Nehmen wir an, Sie möchten die Gesamtzahl der Pakete nach dem Land der Zustellung ermitteln. Wenn Sie mit GROUP BY nicht vertraut sind, könnten Sie eine naive Lösung mit ORDER BY schreiben. SELECT date_of_delivery, city_of_delivery, country_of_delivery FROM package_deliveries ORDER BY country_of_delivery; Nachdem Sie nun die Daten nach Land sortiert haben, wie im Schnappschuss unten gezeigt, beschließen Sie, die Werte manuell zu summieren, um das Ergebnis nach Land zu erhalten. date_of_deliverycity_of_deliverycountry_of_delivery 2024-03-01RijekaCroatia 2024-03-01SplitCroatia 2024-03-01ZagrebCroatia 2024-03-02RijekaCroatia 2024-03-02SplitCroatia 2024-03-02ZagrebCroatia 2024-03-03ZagrebCroatia 2024-03-03SplitCroatia 2024-03-03RijekaCroatia 2024-03-01KrakowPoland 2024-03-01WarsawPoland Aber warum sollten Sie etwas manuell tun, was GROUP BY automatisch tut? Anstatt die Daten nach Land zu sortieren, sollten Sie nach diesem Land gruppieren und SUM() verwenden, um die Daten zu summieren: SELECT country_of_delivery, SUM(number_of_packages) AS total_number_of_packages FROM package_deliveries GROUP BY country_of_delivery ORDER BY country_of_delivery; Sie erhalten dann sofort die gewünschte Ausgabe: country_of_deliverytotal_number_of_packages Croatia2,088 Poland3,743 Turkey28,932 Lesen Sie mehr über die Unterschiede zwischen GROUP BY und ORDER BY und wie Sie GROUP BY und ORDER BY zusammen verwenden können. WHERE und HAVING verwechseln Ein weiterer häufiger Fehler ist der Versuch, aggregierte Werte mit WHERE zu filtern. Das ist nicht möglich - WHERE wird verwendet, um einzelne Zeilen vor der Aggregation zu filtern. Dagegen dient HAVING zum Filtern von Gruppen von Zeilen nach der Aggregation. Beispiel Wenn Sie die durchschnittliche Anzahl der täglich zugestellten Pakete nach Stadt ermitteln und nur die Pakete mit mehr als 500 Paketen anzeigen möchten, könnten Sie diese Abfrage schreiben: SELECT city_of_delivery, AVG(number_of_packages) AS average_number_of_packages FROM package_deliveries WHERE AVG(number_of_packages) > 500 GROUP BY city_of_delivery; Sie wird einen Fehler zurückgeben, da WHERE keine Aggregatfunktion als Argument akzeptiert. (Das bedeutet nicht, dass Sie WHERE nie mit GROUP BY verwenden können; das können Sie, aber nicht, um Gruppen zu filtern.) In diesem Fall sollten Sie HAVING verwenden: SELECT city_of_delivery, AVG(number_of_packages) AS average_number_of_packages FROM package_deliveries GROUP BY city_of_delivery HAVING AVG(number_of_packages) > 500; Es ist die gleiche Abfrage mit AVG() und GROUP BY. Der einzige Unterschied ist HAVING, wobei Sie die Berechnung AVG() mit 500 vergleichen. In der Ausgabe werden nur Städte angezeigt, deren Tagesdurchschnitt über 500 liegt. city_of_deliveryaverage_number_of_packages Izmir1,978.67 Ankara3,046.33 Istanbul4,619.00 Warsaw786.00 Erfahren Sie mehr darüber im Artikel über HAVING vs. WHERE. Auflistung nicht aggregierter Spalten in SELECT, aber nicht in WHERE Die einfache Regel, die Sie sich merken sollten, ist, dass jede nicht aggregierte Spalte, die Sie in SELECT schreiben, auch in GROUP BY enthalten sein sollte. Wenn Sie das nicht tun, weiß die Datenbank nicht, welcher Wert angezeigt werden soll, wenn mehrere verschiedene Werte in derselben Gruppe sind. Beispiel Ein Beispiel: Sie schreiben eine Abfrage, die die Gesamtzahl der Pakete nach Land und Stadt berechnen soll. SELECT country_of_delivery, city_of_delivery, SUM(number_of_packages) total_number_of_packages FROM package_deliveries GROUP BY country_of_delivery; Sicher, Sie haben Land und Stadt in SELECT, aber Sie haben vergessen, die Stadt in GROUP BY einzutragen. Diese Abfrage wird nicht ausgeführt. Sie wird einen Fehler zurückgeben. Auch wenn die Meldungen in PostgreSQL, Oracle und anderen Datenbanken unterschiedlich formuliert sind, ist die Meldung dieselbe: Die Spalte city_of_delivery muss in GROUP BY erscheinen. Selbst wenn der Befehl ausgeführt würde, wäre die Datenbank verwirrt. Sie würde etwa Folgendes denken: "Sie wollen Städte anzeigen, aber nicht nach Stadt gruppieren? Woher soll ich wissen, welche Stadt ich in der Ausgabe anzeigen soll, wenn jedes Land drei Städte hat? Bitte fügen Sie die Städte in GROUP BY ein, damit ich jede Stadt als eigene Gruppe anzeigen kann." Sie helfen also, indem Sie die Stadt der Lieferung in GROUP BY aufnehmen: SELECT country_of_delivery, city_of_delivery, SUM(number_of_packages) total_number_of_packages FROM package_deliveries GROUP BY country_of_delivery, city_of_delivery; Ja, es ist eine Gruppierung nach zwei Spalten, und Sie haben bereits gelernt, wie man das macht. Hier ist die Ausgabe der Abfrage: country_of_deliverycity_of_deliverytotal_number_of_packages CroatiaZagreb930 CroatiaRijeka627 CroatiaSplit531 TurkeyIstanbul13,857 PolandWarsaw2,358 PolandKrakow673 TurkeyAnkara9,139 PolandGdansk712 TurkeyIzmir5,936 Andere Fehler Es gibt auch einige andere Fehler, wie z. B. das Vergessen von GROUP BY mit Aggregatfunktionen oder das Nicht-Gruppieren nach einem eindeutigen Schlüssel. Diese und einige weitere Fehler werden in diesem Artikel über häufige GROUP BY-Fehler behandelt. Weitere SQL GROUP BY Ressourcen Nachdem Sie diesen Überblick über die SQL GROUP BY Klausel gelesen haben, sollten Sie eine Vorstellung von ihrer Verwendung und ihren Herausforderungen haben. Wenn Sie jedoch GROUP BY beherrschen wollen, müssen Sie mehr ins Detail gehen. Das tun Sie am besten, indem Sie sich einige unserer Kurse und Kochbücher ansehen. Hier sind einige meiner Vorschläge zum Weiterlernen: Erstellen einfacher SQL-Berichte - Dieser Kurs für Fortgeschrittene konzentriert sich auf die Feinheiten der Verwendung von GROUP BY - Gruppierung nach mehreren Spalten, Verwendung von HAVING, Kombination von GROUP BY mit CASE WHEN, der Unterschied zwischen COUNT(*) und COUNT(id) usw. GROUP BY Erweiterungen in SQL - Dieser Kurs behandelt CUBE, ROLLUP und GROUPING SETS. SQL-Praxis - Die Kurse in diesem Bereich haben Abschnitte, die sich mit verschiedenen SQL-Themen befassen, darunter auch eine ganze Reihe von GROUP BY. Und vergessen Sie nicht unsere Artikel mit den GROUP BY Beispielen. Zwei meiner Favoriten sind SQL-Praxis: 10 GROUP BY-Übungen mit detaillierten Lösungen und die 9 wichtigsten SQL GROUP BY-Interview-Fragen. Darüber hinaus gibt es ein SQL for Data Analysis Cheat Sheet, das einen eigenen Abschnitt für GROUP BY enthält. Viel Spaß beim Lernen! Tags: Aggregatfunktionen GROUP BY