Heute tauchen wir in ein noch spezielleres, aber wichtiges Thema ein: die Funktionen GREATEST() und LEAST(). Du lernst, wie du die größten und kleinsten Werte aus mehreren Spalten findest und – ganz wichtig – wie NULL ihr Verhalten beeinflusst.
Wenn du jemals nach dem Wichtigsten in deinem Leben gesucht hast (Liebe, Traumjob oder das beste Pizza-Rezept), dann verstehst du sofort, wofür die Funktionen GREATEST() und LEAST() da sind. Diese Funktionen helfen dir, den größten oder kleinsten Wert in einer Liste von Dingen zu finden. Nur dass du statt Pizza mit Zahlen, Daten, Strings und anderen Daten in PostgreSQL arbeitest.
GREATEST()
GREATEST() gibt den größten Wert aus dem übergebenen Set zurück.
Syntax:
GREATEST(value1, value2, ..., valueN)
LEAST()
LEAST() macht das Gegenteil: Sie sucht den kleinsten Wert.
Syntax:
LEAST(value1, value2, ..., valueN)
Beispiel:
Angenommen, wir haben eine Tabelle students_scores, in der die Noten der Studierenden für drei Prüfungen gespeichert sind:
| student_id | exam_1 | exam_2 | exam_3 |
|---|---|---|---|
| 1 | 85 | 90 | 82 |
| 2 | NULL | 76 | 89 |
| 3 | 94 | NULL | 88 |
Anwendung von GREATEST() und LEAST():
SELECT
student_id,
GREATEST(exam_1, exam_2, exam_3) AS highest_score,
LEAST(exam_1, exam_2, exam_3) AS lowest_score
FROM students_scores;
Ergebnis:
| student_id | highest_score | lowest_score |
|---|---|---|
| 1 | 90 | 82 |
| 2 | 89 | NULL |
| 3 | 94 | NULL |
Wie beeinflusst NULL GREATEST() und LEAST()?
Jetzt kommen wir zum spannendsten Teil. Zusammen mit den Werten in der Tabelle kann es auch NULL geben. Und wie wir schon wissen, ist NULL so eine mysteriöse Entität, die das Fehlen von Daten oder einen unbekannten Wert bedeutet. Lass uns anschauen, was passiert, wenn NULL in die Funktionen GREATEST() und LEAST() in PostgreSQL gelangt.
Verhalten von NULL:
In PostgreSQL haben die Funktionen GREATEST() und LEAST() ein besonderes Verhalten: Sie ignorieren NULL-Werte beim Suchen nach dem größten oder kleinsten Wert unter ihren Argumenten. Wichtig: Der einzige Fall, in dem diese Funktionen NULL zurückgeben, ist, wenn alle ihre Argumente NULL sind.
Beispiel:
SELECT
GREATEST(10, 20, NULL, 5) AS greatest_value,
LEAST(10, 20, NULL, 5) AS least_value;
Ergebnis:
| greatest_value | least_value |
|---|---|
| 20 | 5 |
Wie du siehst, wurde NULL ignoriert und die Funktionen haben den größten und kleinsten Wert aus den vorhandenen (10, 20, 5) zurückgegeben.
Und hier ein Beispiel, wenn alle Argumente NULL sind:
Beispiel:
SELECT
GREATEST(NULL, NULL) AS greatest_nulls,
LEAST(NULL, NULL) AS least_nulls;
Ergebnis:
| greatest_nulls | least_nulls |
|---|---|
| NULL | NULL |
Wie kann man Probleme mit NULL vermeiden?
Auch wenn PostgreSQL NULL standardmäßig ignoriert, brauchst du manchmal ein anderes Verhalten. Zum Beispiel, wenn du möchtest, dass NULL als ein bestimmter Wert (z.B. 0 oder ein anderer Default-Wert) behandelt wird, wenn du das Maximum/Minimum bestimmst. In solchen Fällen kannst du die Funktion COALESCE() verwenden.
Die Funktion COALESCE(arg1, arg2, ...) gibt das erste nicht-NULL-Argument aus ihrer Liste zurück. Damit kannst du NULL vorab durch einen sinnvollen Wert ersetzen, bevor du ihn an GREATEST() oder LEAST() weitergibst.
Beispiel 1: NULL durch 0 ersetzen
Angenommen, wir wollen, dass das Fehlen einer Note (NULL) als 0 gilt. Wir können COALESCE() nutzen, um einen Default-Wert einzusetzen.
Hier ist unsere Ausgangstabelle:
| student_id | exam_1 | exam_2 | exam_3 |
|---|---|---|---|
| 1 | 90 | 85 | 82 |
| 2 | NULL | 89 | NULL |
| 3 | NULL | NULL | 94 |
Query:
SELECT
student_id,
GREATEST(
COALESCE(exam_1, 0),
COALESCE(exam_2, 0),
COALESCE(exam_3, 0)
) AS highest_score,
LEAST(
COALESCE(exam_1, 0),
COALESCE(exam_2, 0),
COALESCE(exam_3, 0)
) AS lowest_score
FROM students_scores;
Ergebnis:
| student_id | highest_score | lowest_score |
|---|---|---|
| 1 | 90 | 82 |
| 2 | 89 | 0 |
| 3 | 94 | 0 |
Beispiel 2: NULL durch Wert aus anderer Spalte ersetzen
Manchmal willst du statt eines festen Werts (wie 0) lieber einen Wert aus einer anderen Spalte einsetzen. Zum Beispiel, wenn exam_3 fehlt, soll der Wert aus exam_1 genommen werden.
SELECT
student_id,
GREATEST(
exam_1,
exam_2,
COALESCE(exam_3, exam_1)
) AS highest_score
FROM students_scores;
Angenommen, wir haben diese Tabelle:
| student_id | exam_1 | exam_2 | exam_3 |
|---|---|---|---|
| 1 | 90 | 85 | 82 |
| 2 | NULL | 89 | NULL |
| 3 | 70 | NULL | NULL |
Ergebnis der Query:
| student_id | highest_score |
|---|---|
| 1 | 90 |
| 2 | 89 |
| 3 | 70 |
Praktische Cases
Case 1: Maximale Rabatt finden
| order_id | discount_1 | discount_2 | discount_3 |
|---|---|---|---|
| 101 | 5 | 10 | 7 |
| 102 | NULL | 3 | 8 |
| 103 | 15 | NULL | NULL |
| 104 | NULL | NULL | NULL |
Du arbeitest mit der Tabelle orders, wo jede Bestellung drei verschiedene Rabatttypen haben kann. Du musst den maximalen Rabatt für jede Bestellung finden.
SELECT
order_id,
GREATEST(discount_1, discount_2, discount_3) AS max_discount
FROM orders;
Ergebnis:
| order_id | max_discount |
|---|---|
| 101 | 10 |
| 102 | 8 |
| 103 | 15 |
| 104 | NULL |
Case 2: Minimale Produktpreis finden
In der Tabelle products werden die Preise der Produkte in drei Währungen (USD, EUR, GBP) gespeichert. Deine Aufgabe ist es, für jedes Produkt den minimalen Preis zu finden.
| product_id | price_usd | price_eur | price_gbp |
|---|---|---|---|
| 1 | 100 | 95 | 80 |
| 2 | NULL | 150 | 140 |
| 3 | 200 | NULL | NULL |
| 4 | NULL | NULL | NULL |
SELECT
product_id,
LEAST(price_usd, price_eur, price_gbp) AS lowest_price
FROM products;
| product_id | lowest_price |
|---|---|
| 1 | 80 |
| 2 | 140 |
| 3 | 200 |
| 4 | NULL |
Wenn alle Preise NULL sind, ist das Ergebnis auch NULL
Typische Fehler bei der Verwendung von GREATEST() und LEAST()
Fehler 1: Unerwartetes Ergebnis wegen NULL.
Früher in der Vorlesung haben wir ausführlich besprochen, wie NULL GREATEST() und LEAST() in PostgreSQL beeinflusst. Der Hauptfehler ist, dass User, die das Verhalten von NULL aus anderen Datenbanksystemen gewohnt sind (wo ein NULL das ganze Ergebnis "vergiftet"), das gleiche Verhalten auch von PostgreSQL erwarten.
Wie zeigt sich der Fehler: Du könntest fälschlicherweise denken, dass wenn im Argument-Set ein NULL ist, die Funktion immer NULL zurückgibt. Dadurch benutzt du vielleicht unnötig COALESCE() für alle Argumente, was die Query komplizierter und langsamer machen kann, wenn in deinem Fall NULL einfach ignoriert werden sollte.
Fehler 2: Verwendung von GREATEST() und LEAST() mit inkompatiblen Typen.
Die Funktionen GREATEST() und LEAST() sind dafür gedacht, Werte vom selben Datentyp oder von Typen zu vergleichen, die implizit konvertiert werden können. Wenn du versuchst, Werte von völlig unterschiedlichen, inkompatiblen Typen zu vergleichen, bekommst du einen Fehler.
Wie zeigt sich der Fehler: Du bekommst eine Fehlermeldung, die auf die Inkompatibilität der Datentypen hinweist.
GO TO FULL VERSION