| PostgreSQL: Das Offizielle Handbuch | ||||
|---|---|---|---|---|
| Zurück | Schnell zurück | Schnell nach vorne | Nach vorne | |
SELECT [ ALL | DISTINCT [ ON ( ausdruck [, ...] ) ] ]
* | ausdruck [ AS ausgabename ] [, ...]
[ FROM from_element [, ...] ]
[ WHERE bedingung ]
[ GROUP BY ausdruck [, ...] ]
[ HAVING bedingung [, ...] ]
[ { UNION | INTERSECT | EXCEPT } [ ALL ] select ]
[ ORDER BY ausdruck [ ASC | DESC | USING operator ] [, ...] ]
[ LIMIT { anzahl | ALL } ]
[ OFFSET start ]
[ FOR UPDATE [ OF tabellenname [, ...] ] ]
wobei from_element eins der Folgenden sein kann:
[ ONLY ] tabellenname [ * ] [ [ AS ] alias [ ( spaltenalias [, ...] ) ] ]
( select ) [ AS ] alias [ ( spaltenalias [, ...] ) ]
funktionsname ( [ argument [, ...] ] ) [ AS ] alias [ ( spaltenalias [, ...] | spaltendefinition [, ...] ) ]
funktionsname ( [ argument [, ...] ] ) AS ( spaltendefinition [, ...] )
from_element [ NATURAL ] verbundtyp from_element [ ON verbundbedingung | USING ( spalte [, ...] ) ]SELECT liest Zeilen aus einer oder mehreren Tabellen. Der prinzipielle Ablauf eines SELECT-Befehls sieht folgendermaßen aus:
Alle Elemente in der FROM-Liste werden berechnet. (Jedes Element in der FROM-Liste ist eine echte oder virtuelle Tabelle.) Wenn mehrere Elemente in der FROM-Liste angegeben sind, dann werden sie per Kreuzverbund verknüpft. (Siehe unten unter Die FROM-Klausel.)
Wenn die WHERE-Klausel angegeben ist, dann werden alle Zeilen, die die angegebene Bedingung nicht erfüllen, vom Ergebnis entfernt. (Siehe unten unter Die WHERE-Klausel.)
Wenn die GROUP BY-Klausel angegeben ist, dann werden die Ergebniszeilen in Gruppen unterteilt, die in einem oder mehreren Werten übereinstimmen. Wenn die HAVING-Klausel vorhanden ist, dann entfernt sie die Gruppen aus dem Ergebnis, die die angegebene Bedingung nicht erfüllen. (Siehe unten unter Die GROUP BY-Klausel und Die HAVING-Klausel.)
Mit den Operatoren UNION, INTERSECT und EXCEPT kann das Ergebnis von mehreren SELECT-Befehlen in eine einzige Ergebnismenge zusammengefasst werden. Der Operator UNION gibt alle Zeilen zurück, die in einer oder beiden Ergebnismengen enthalten sind. Der Operator INTERSECT gibt alle Zeilen zurück, die in beiden Ergebnismengen enthalten sind. Der Operator EXCEPT gibt alle Zeilen zurück, die in der ersten Ergebnismenge enthalten sind, aber nicht in der zweiten. In allen drei Fällen werden doppelte Zeilen entfernt, wenn ALL nicht angegeben ist. (Siehe unten unter Die UNION-Klausel, Die INTERSECT-Klausel und Die EXCEPT-Klausel.)
Die eigentlichen Ergebniszeilen werden von den SELECT-Ausgabeausdrücken aus jeder ausgewählten Zeilen berechnet. (Siehe unten unter Die SELECT-Liste.)
Wenn die ORDER BY-Klausel angegeben ist, dann werden die zurückgegebenen Zeilen in der angegebenen Reihenfolge sortiert. Wenn ORDER BY nicht angegeben ist, dann werden die Zeilen in der Reihenfolge zurückgegeben, die das System am schnellsten erzeugen kann. (Siehe unten unter Die ORDER BY-Klausel.)
Wenn die Klauseln LIMIT oder OFFSET angegeben sind, dann gibt der SELECT-Befehl nur eine Teilmenge der Ergebniszeilen zurück. (Siehe unten unter Die LIMIT-Klausel.)
DISTINCT entfernt alle doppelten Zeilen aus dem Ergebnis. DISTINCT ON entfernt Zeilen, die in den angegebenen Ausdrücken übereinstimmen. ALL (die Voreinstellung) gibt alle Zeilen zurück. (Siehe unten unter Die DISTINCT-Klausel.)
Mit der Klausel FOR UPDATE sperrt der SELECT-Befehl die ausgewählten Zeilen gegen gleichzeitige Aktualisierungen. (Siehe unten unter Die FOR UPDATE-Klausel.)
Um eine Tabelle lesen zu können müssen Sie das Privileg SELECT für die Tabelle haben. Wenn Sie FOR UPDATE verwenden, dann benötigen Sie zusätzlich das Privileg UPDATE.
Die FROM-Klausel gibt eine oder mehrere Quelltabellen für den SELECT-Befehl an. Wenn mehrere Quellen angegeben sind, dann ist das Ergebnis das kartesische Produkt (der Kreuzverbund) aller Quellen. Aber gewöhnlich werden Bedingungen angegeben, die die zurückgegebenen Zeilen auf eine kleine Teilmenge des Kreuzverbundes beschränken.
Die FROM-Klausel kann folgende Elemente enthalten:
Der Name einer bestehenden Tabelle oder Sicht (möglicherweise mit Schemaqualifikation). Wenn ONLY angegeben ist, dann wird nur diese Tabelle durchsucht. Wenn ONLY nicht angegeben ist, dann werden die Tabelle und alle Tabellen, die von dieser erben, (falls vorhanden) durchsucht. * kann an den Tabellennamen angehängt werden um anzuzeigen, dass Tabellen, die von dieser erben, mit durchsucht werden sollen, aber das ist in der aktuellen Version das normale Verhalten. (In Versionen vor 7.1 war ONLY die Voreinstellung.) Das voreingestellte Verhalten kann mit dem Konfigurationsparameter sql_interitance eingestellt werden.
Ein Ersatzname für das FROM-Element, das den Aliasnamen enthält. Ein Aliasname kann zur Abkürzung von Namen oder um bei Selbstverbunden (wo die selbe Tabelle mehrfach verwendet wird) Zweideutigkeiten auszuschließen verwendet werden. Wenn ein Aliasname verwendet wird, dann versteckt er den eigentlichen Namen der Tabelle oder Funktion; zum Beispiel bei FROM foo AS f muss der Rest des SELECT auf dieses FROM-Element mit f verweisen, nicht foo. Wenn ein Aliasname angegeben wird, dann können auch Aliasnamen für die Spalten der Tabelle angegeben werden.
SELECT-Befehle können als Unteranfrage in der FROM-Klausel erscheinen. Das verhält sich dann wie eine temporäre Tabelle, die nur für die Dauer des SELECT-Befehls besteht. Beachten Sie, dass alle Unteranfragen in Klammern stehen müssen und Aliasnamen haben müssen.
Funktionsaufrufe können in der FROM-Klausel stehen. (Das ist besonders nützlich bei Funktionen, die Ergebnismengen zurückgeben, aber jede Funktion kann verwendet werden.) Das verhält sich, als ob die Ergebnisse der Funktion in einer temporären Tabelle gespeichert wären, die nur für die Dauer des SELECT-Befehls besteht. Ein Aliasname kann auch angegeben werden. Wenn ein Aliasname angegeben wird, dann kann auch eine Liste von Spaltenaliasnamen Ersatznamen für die Attribute des zusammengesetzten Ergebnistyps der Funktion angeben. Wenn die Funktion mit Rückgabetyp record definiert wurde, dann muss ein Alias oder das Schlüsselwort AS angegeben werden, gefolgt von einer Spaltendefinitionsliste der Form ( spaltenname datentyp [, ... ] ). Die Spaltendefinitionen müssen mit den tatsächlich von der Funktion zurückgegebenen Spalten in Zahl und Typ übereinstimmen.
Einer der folgenden:
[ INNER ] JOIN
LEFT [ OUTER ] JOIN
RIGHT [ OUTER ] JOIN
FULL [ OUTER ] JOIN
CROSS JOIN
Bei den Verbundtypen INNER und OUTER muss eine Verbundbedingung angegeben werden, und zwar genau eine der folgenden: NATURAL, ON verbundbedingung oder USING (spalte [, ...]). Die Bedeutungen werden weiter unten beschrieben. Bei CROSS JOIN darf keine dieser Klauseln erscheinen.
Eine JOIN-Klausel kombiniert zwei FROM-Elemente. (Verwenden Sie Klammern um wenn nötig die Reihenfolge der Verschachtelung zu kontrollieren.)
CROSS JOIN und INNER JOIN erzeugen einfach das kartesische Produkt, genauso als ob die zwei Elemente direkt in der FROM-Liste aufgezählt worden wären. CROSS JOIN hat die selbe Bedeutung wie INNER JOIN ON (true), das heißt, keine Zeilen werden durch eine Bedingung entfernt. Diese Verbundtypen sind nur eine bequemere Schreibweise, da sie nichts machen, was man nicht auch mit einem einfachen FROM und WHERE erreichen könnte.
LEFT OUTER JOIN ergibt alle Zeilen des qualifizierten kartesischen Produkts (d.h. alle kombinierten Zeilen, die die Verbundbedingung erfüllen), plus einmal jede Zeile der linken Tabelle, für die es keine Zeile in der rechten Tabelle gibt, mit der die Verbundbedingung erfüllt werden kann. Diese linken Zeilen wird auf die volle Breite der verbundenen Zeile erweitert, indem die Spalten der rechten Tabelle mit NULL-Werten aufgefüllt werden. Beachten Sie, dass nur die Bedingung der JOIN-Klausel selbst beim Vergleich der Zeilen verwendet wird. Bedingungen in den äußeren Klauseln werden später angewendet.
Umgekehrt ergibt RIGHT OUTER JOIN alle verbundenen Zeilen plus einmal jede Zeile der rechten Tabelle ohne passende Zeile in der linken Tabelle (mit NULL-Werten nach links erweitert). Das ist nur eine alternative Schreibweise, weil man das auch als LEFT OUTER JOIN mit den linken und rechten Eingabewerten vertauscht schreiben kann.
FULL OUTER JOIN ergibt alle verbundenen Zeilen, plus jede Zeile der linken Tabelle ohne passende rechte Zeile (mit NULL-Werten nach rechts erweitert), plus jede Zeile der rechten Tabelle ohne passende linke Zeile (mit NULL-Werten nach links erweitert).
verbundbedingung ist ein Ausdruck, der einen Wert des Typs boolean ergibt (ähnlich wie eine WHERE-Klausel), der angibt, welche Zeilen in einem Verbund zueinander gehören sollen.
Eine Klausel der Form USING ( a, b, ... ) ist eine Abkürzung für ON linke_tabelle.a = rechte_tabelle.a AND linke_tabelle.b = rechte_tabelle.b .... Außerdem enthält bei USING das Ergebnis des Verbunds nur eine Ausgabe für jedes paar von äquivalenten Spalten, nicht beide.
NATURAL ist eine Abkürzung für eine USING-Liste, die alle Spalten der beiden Tabellen aufzählt, die die gleichen Namen haben.
Die optionale WHERE-Klausel hat folgende allgemeine Form:
WHERE bedingung
wobei bedingung ein beliebiger Ausdruck ist, der ein Ergebnis des Typs boolean hat. Jede Zeile, die diese Bedingung nicht erfüllt, wird aus dem Ergebnis des SELECT-Befehls entfernt. Eine Zeile erfüllt die Bedingung, wenn der Ausdruck „wahr“ ergibt, wenn die tatsächlichen Zeilenwerte für etwaige Variablen eingesetzt werden.
Die optionale GROUP BY-Klausel hat folgende allgemeine Form:
GROUP BY ausdruck [, ...]
GROUP BY fasst alle Zeilen, die den gleichen Wert für die Gruppierungsausdrücke haben, zu jeweils einer Zeile zusammen. ausdruck kann der Name einer Eingabespalte, die Nummer einer Ausgabespalte (SELECT-Liste) oder ein beliebiger Ausdruck aus Eingabespaltenwerten sein. Bei Zweideutigkeiten werden Namen in GROUP BY als Eingabespalte anstatt als Ausgabespalte interpretiert.
Aggregatfunktionen berechnen jeweils einen Wert aus allen Zeilen einer Gruppe. (Ohne GROUP BY berechnet eine Aggregatfunktion einen einzelnen Wert aus allen ausgewählten Zeilen.) Wenn GROUP BY verwendet wird, dann ist es nicht zulässig, dass Ausdrücke in der SELECT-Liste auf ungruppierte Spalten verweisen, außer über Aggregatfunktionen, da es für eine ungruppierte Spalte mehr als einen möglichen Wert geben würde.
Die optionale HAVING-Klausel hat die allgemeine Form
HAVING bedingung
wobei bedingung genauso wie in der WHERE-Klausel funktioniert.
HAVING entfernt Gruppenzeilen, die die Bedingung nicht erfüllen. HAVING unterscheidet sich von WHERE: WHERE filtert einzelne Zeilen vor der Anwendung von GROUP BY, während HAVING die von GROUP BY erzeugten Zeilen filtert. Jede Spalte, die in bedingung verwendet wird, muss eindeutig auf eine gruppierte Spalte verweisen, es sei denn der Verweis steht in einer Aggregatfunktion.
Die UNION-Klausel hat diese allgemeine Form:
select_befehl UNION [ ALL ] select_befehl
select_befehl ist ein beliebiger SELECT-Befehl ohne ORDER BY, LIMIT und FOR UPDATE. (ORDER BY und LIMIT können in einem Unterausdruck stehen, wenn er in Klammern steht. Ohne Klammern werden diese Klauseln auf das Ergebnis von UNION angewendet, nicht auf den rechten Teilausdruck.)
Der Operator UNION berechnet die Vereingungsmenge der Zeilen, die von beiden SELECT-Befehlen geliefert werden. Eine Zeile ist in der Vereinigungsmenge, wenn sie in mindestens einer der beiden Ergebnismengen erscheint. Die beiden SELECT-Befehle, die die direkten Operanden von UNION sind, müssen die gleiche Anzahl von Spalten ergeben und die einander entsprechenden Spalten müssen kompatible Datentypen haben.
Das Ergebnis von UNION enthält keine doppelten Zeilen, außer wenn die Option ALL angegeben ist. ALL verhindert das Entfernen von Duplikaten.
Mehrere UNION-Operatoren im selben SELECT-Befehl werden von links nach rechts ausgewertet. Klammern können verwendet werden um die Reihenfolge zu ändern.
Im Ergebnis oder in den Operanden von UNION kann die Klausel FOR UPDATE kann gegenwärtig nicht verwendet werden.
Die INTERSECT-Klausel hat diese allgemeine Form:
select_befehl INTERSECT [ ALL ] select_befehl
select_befehl ist ein beliebiger SELECT-Befehl ohne ORDER BY, LIMIT und FOR UPDATE.
Der Operator INTERSECT berechnet die Schnittmenge der Zeilen, die von beiden SELECT-Befehlen geliefert werden. Eine Zeile ist in der Schnittmenge, wenn sie in beiden Ergebnismengen erscheint.
Das Ergebnis von INTERSECT enthält keine doppelten Zeilen, außer wenn die Option ALL angegeben ist. Wenn ALL angegeben ist, dann wird eine Zeile, die in der linken Tabelle m-mal und in der rechten Tabelle n-mal erscheint, im Ergebnis min(m,n)-mal erscheinen.
Mehrere INTERSECT-Operatoren im selben SELECT-Befehl werden von links nach rechts ausgewertet, außer wenn Klammern es anders regeln. INTERSECT bindet enger als UNION. Das heißt A UNION B INTERSECT C wird als A UNION (B INTERSECT C) gelesen.
Die EXCEPT-Klausel hat diese allgemeine Form:
select_befehl EXCEPT [ ALL ] select_befehl
select_befehl ist ein beliebiger SELECT-Befehl ohne ORDER BY, LIMIT und FOR UPDATE.
Der Operator EXCEPT berechnet die Menge der Zeilen, die im Ergebnis des linken SELECT-Befehls, aber nicht im Ergebnis des rechten erscheinen.
Das Ergebnis von EXCEPT enthält keine doppelten Zeilen, außer wenn die Option ALL angegeben ist. Wenn ALL angegeben ist, dann wird eine Zeile, die in der linken Tabelle m-mal und in der rechten Tabelle n-mal erscheint, im Ergebnis max(m-n,0)-mal erscheinen.
Mehrere EXCEPT-Operatoren im selben SELECT-Befehl werden von links nach rechts ausgewertet, außer wenn Klammern es anders regeln. EXCEPT bindet im gleiche Maße wie UNION.
Die SELECT-Liste (zwischen den Schlüsselwörtern SELECT und FROM) enthält Ausdrücke, die die Ausgabezeilen des SELECT-Befehls berechnen. Die Ausdrücke können auf die in der FROM-Klausel berechneten Spalten verweisen (und tun das in der Regel auch). Mit der Klausel AS ausgabename kann einer Ausgabespalte ein anderer Name gegeben werden. Dieser Name wird hauptsächlich als Spaltenkopf in der Ausgabe verwendet. Er kann aber auch in den Klauseln ORDER BY und GROUP BY verwendet werden, nicht aber in den Klauseln WHERE und HAVING, dort müssen Sie den Ausdruck ausschreiben.
Anstelle eines Ausdrucks kann in der Liste auch * geschrieben werden, als Abkürzung für alle Spalten der ausgewählten Zeilen. Außerdem kann man tabellenname.* als Abkürzung für die Spalten aus nur dieser Tabelle schreiben.
Die optionale ORDER BY-Klausel hat diese allgemeine Form:
ORDER BY ausdruck [ ASC | DESC | USING operator ] [, ...]
ausdruck kann der Name oder die Nummer einer Ausgabespalte (SELECT-Liste) oder ein beliebiger Ausdruck aus Eingabespaltenwerten sein.
Die ORDER BY-Klausel sortiert die Ergebniszeilen anhand der angegebenen Ausdrücke. Wenn zwei Zeilen nach dem am weitesten links stehenden Ausdruck gleich sind, dann werden sie anhand des nächsten Ausdrucks verglichen uns so weiter. Wenn sie nach allen angegebenen Ausdrücken gleich sind, dann werden sie in zufälliger Reihenfolge zurückgegeben.
Eine Nummer verweist auf eine Ergebnisspalte gezählt von links nach rechts. Dadurch kann man auf Spalten verweisen, die keinen eindeutigen Namen haben. Das ist aber niemals absolut notwendig, denn man kann jeder Ergebnisspalte mit der AS-Klausel einen Namen zuweisen.
Man kann in der ORDER BY-Klausel auch beliebige Ausdrücke angeben, einschließlich Spalten, die nicht in der SELECT-Liste erscheinen. Der folgende Befehl ist also gültig:
SELECT name FROM verleihe ORDER BY code;
Eine Beschränkung ist jedoch, dass eine ORDER BY-Klausel, die auf das Ergebnis von UNION, INTERSECT oder EXCEPT angewendet wird, nur den Namen oder die Nummer von Ausgabespalten angeben darf, keine Ausdrücke.
Wenn ein Ausdruck in ORDER BY sowohl als Name einer Ergebnisspalte als auch als Name einer Eingabespalte interpretiert werden kann, dann interpretiert ORDER BY ihn als Name der Ausgabespalte. Dies ist das Gegenteil von dem, was GROUP BY in dieser Situation machen würde. Diese Unregelmäßigkeit ist notwendig, um mit dem SQL-Standard kompatibel zu sein.
Wahlweise kann man nach jedem Ausdruck in der ORDER BY-Klausel das Schlüsselwort ASC für aufsteigende Reihenfolge oder DESC für abfallende Reihenfolge schreiben. Wenn keines angegeben ist, dann ist ASC die Voreinstellung. Als Alternative kann man auch einen bestimmten Sortieroperator mit der Klausel USING angeben. ASC entspricht USING < und DESC entspricht USING >.
NULL-Werte werden höher als alle anderen Werten einsortiert. Anders ausgedrückt, bei aufsteigender Reihenfolge erscheinen NULL-Werte am Ende und bei abfallender Reihenfolge erscheinen NULL-Werte am Anfang.
Die LIMIT-Klausel besteht aus zwei unabhängigen Klauseln:
LIMIT { anzahl | ALL }
OFFSET startanzahl gibt die Anzahl der Zeilen an, die höchstens zurückgegeben werden sollen. start gibt die Anzahl der Zeilen an, die übersprungen werden sollen bevor Zeilen zurückgegeben werden.
Wenn LIMIT verwendet wird, dann ist es empfehlenswert, eine ORDER BY-Klausel zu verwenden, die die Ergebniszeilen in eine eindeutige Ordnung bringt. Ansonsten erhalten Sie eine nicht vorhersagbare Teilmenge der Ergebniszeilen der Anfrage. Sie könnten zum Beispiel die Zeilen 10 bis 20 anfordern, aber 10 bis 20 nach welcher Reihenfolge? Die Reihenfolge ist unbekannt, wenn ORDER BY nicht verwendet wird.
Der Anfrageoptimierer zieht die LIMIT-Klausel mit in Betracht, wenn er einen Ausführungsplan für eine Anfrage erstellt, was heißt, dass man sehr wahrscheinlich unterschiedliche Pläne (die unterschiedliche Zeilenreihenfolgen ergeben) erhält, wenn man die LIMIT- und OFFSET-Werte verändert. Wenn man folglich die LIMIT- und OFFSET-Werte variiert, um verschiedene Teilmengen eines Anfrageergebnisses auszuwählen, dann wird man widersprüchliche Ergebnisse erhalten, wenn man keine voraussagbare Reihenfolge mit ORDER BY erzwingt. Das ist kein Fehler; das Verhalten folgt aus der Tatsache, dass SQL keine Gewähr dafür gibt, dass das Ergebnis einer Anfrage in einer bestimmten Reihenfolge abgeliefert wird, außer wenn ORDER BY verwendet wird um die Reihenfolge zu beeinflussen.
Wenn DISTINCT angegeben ist, dann werden doppelte Zeilen aus der Ergebnismenge entfernt. (Eine Zeile wird für jede Gruppe doppelter Zeilen behalten.) ALL ist das Gegenteil: Alle Zeilen werden behalten; das ist auch die Voreinstellung.
DISTINCT ON ( ausdruck [, ...] ) behält nur die erste Zeile jeder Gruppe von Zeilen, bei denen die angegebenen Ausdrücke gleich sind. Die Ausdrücke in DISTINCT ON werden mit den selben Regeln wie in der ORDER BY-Klausel interpretiert (siehe oben). Beachten Sie, dass die „erste Zeile“ einer Menge nicht vorhergesagt werden kann, außer wenn ORDER BY verwendet wird um sicherzustellen, dass die gewünschte Zeile zuerst erscheint. Zum Beispiel ermittelt folgende Anfrage den neuesten Wetterbericht jedes Ortes:
SELECT DISTINCT ON (ort) ort, zeit, bericht
FROM wetterberichte
ORDER BY ort, zeit DESC;Wenn ORDER BY nicht verwendet worden wäre um die Zeitangaben an jedem Ort abfallend zu sortieren, würden wir für jeden Ort einen zufällig ausgewählten Bericht erhalten.
Die FOR UPDATE-Klausel hat diese Form:
FOR UPDATE [ OF tabellenname [, ...] ]
Durch FOR UPDATE wird jede von dem SELECT-Befehl zurückgegebene Zeile wie bei einer Aktualisierung gesperrt. Dadurch wird verhindert, dass andere Transaktionen diese Zeile ändern oder löschen können, bevor diese Transaktion beendet ist. Das heißt, wenn eine andere Transaktion in diesen Zeilen ein UPDATE, DELETE oder SELECT FOR UPDATE versucht, dann blockiert sie, bis die aktuelle Transaktion beendet ist. Wenn eine andere Transaktion eine ausgewählte Zeile oder Zeilen schon durch UPDATE, DELETE oder SELECT FOR UPDATE gesperrt hat, dann wartet SELECT FOR UPDATE bis die andere Transaktion zu Ende geht und wird dann die aktualisierte Zeile sperren und zurückgeben (oder gar nichts machen, wenn die Zeile gelöscht wurde). Ausführlichere Informationen über dieses Thema finden Sie in Kapitel 12.
Wenn bestimmte Tabellen in FOR UPDATE aufgezählt sind, dann werden nur Zeilen, die aus diesen Tabellen kommen, gesperrt; alle anderen Tabellen, die in dem SELECT-Befehl verwendet werden, werden ganz normal gelesen.
In Zusammenhängen, wo es nicht klar ist, aus welcher Tabelle eine Zeile kam, kann FOR UPDATE nicht verwendet werden, zum Beispiel nicht, wenn Aggregatfunktionen verwendet werden.
FOR UPDATE kann vor LIMIT stehen um kompatibel mit PostgreSQL-Versionen vor 7.3 zu sein. Das es aber im Prinzip nach LIMIT ausgeführt wird, empfehlen wir, es auch dort hinzuschreiben.
Ein Verbund der Tabellen filme und verleihe:
SELECT f.titel, f.vid, v.name, f.prod_datum, f.genre
FROM verleihe v, filme f
WHERE f.vid = v.vid
titel | vid | name | prod_datum | genre
-------------------+-----+--------------+------------+------------
The Third Man | 101 | British Lion | 1949-12-23 | Drama
The African Queen | 101 | British Lion | 1951-08-11 | Romantisch
...
Summiere die Spalte länge aller Filme und gruppiere die Ergebnisse nach Genre:
SELECT genre, sum(länge) AS gesamt FROM filme GROUP BY genre; genre | gesamt ------------+-------- Action | 07:34 Comedy | 02:58 Drama | 14:28 Musical | 06:42 Romantisch | 04:38
Summiere die Spalte länge aller Filme, gruppiere die Ergebnisse nach Genre und zeige jene Gruppen, deren Gesamtlänge kleiner als 5 Stunden ist:
SELECT genre, sum(länge) AS gesamt
FROM filme
GROUP BY genre
HAVING sum(länge) < interval '5 hours';
genre | gesamt
------------+--------
Comedy | 02:58
Romantisch | 04:38
Die folgenden zwei Beispiele sind gleichbedeutende Möglichkeiten, die einzelnen Ergebnisse nach dem Inhalt der zweiten Spalte (name) zu sortieren:
SELECT * FROM verleihe ORDER BY name; SELECT * FROM verleihe ORDER BY 2; vid | name -----+------------------ 109 | 20th Century Fox 110 | Bavaria Atelier 101 | British Lion 107 | Columbia 102 | Jean Luc Godard 113 | Luso films 104 | Mosfilm 103 | Paramount 106 | Toho 105 | United Artists 111 | Walt Disney 112 | Warner Bros. 108 | Westward
Dieses Beispiel zeigt, wie man die Vereinigungsmenge der zwei Tabellen verleihe und schauspieler ermittelt und das Ergebnis auf diejenigen, die mit W beginnen, beschränkt. Duplikate sind nicht erwünscht, also wird das Schlüsselwort ALL weggelassen.
verleihe: schauspieler:
vid | name id | name
-----+-------------- ----+----------------
108 | Westward 1 | Woody Allen
111 | Walt Disney 2 | Warren Beatty
112 | Warner Bros. 3 | Walter Matthau
... ...
SELECT verleihe.name
FROM verleihe
WHERE verleihe.name LIKE 'W%'
UNION
SELECT schauspieler.name
FROM schauspieler
WHERE schauspieler.name LIKE 'W%';
name
----------------
Walt Disney
Walter Matthau
Warner Bros.
Warren Beatty
Westward
Woody Allen
Dieses Beispiel zeigt, wie eine Funktion in der FROM-Liste verwendet werden kann, mit oder ohne Spaltendefinitionsliste.
CREATE FUNCTION verleihe(int) RETURNS SETOF verleihe AS '
SELECT * FROM verleihe WHERE vid = $1;
' LANGUAGE SQL;
SELECT * FROM verleihe(111);
vid | name
-----+-------------
111 | Walt Disney
CREATE FUNCTION verleihe_2(int) RETURNS SETOF record AS '
SELECT * FROM verleihe WHERE vid = $1;
' LANGUAGE SQL;
SELECT * FROM verleihe_2(111) AS (f1 int, f2 text);
f1 | f2
-----+-------------
111 | Walt Disney
Natürlich ist der Befehl SELECT mit dem SQL-Standard kompatibel. Aber es gibt einige Erweiterungen und fehlende Funktionalität.
In PostgreSQL kann man die FROM-Klausel weglassen. Das hat einfache Anwendung, wie die Auswertung von einfachen Ausdrücken:
SELECT 2+2;
?column?
----------
4In einigen anderen SQL-Datenbanken geht das nur, wenn man eine einzeilige Pseudotabelle in dem SELECT-Befehl angibt.
Eine weniger offensichtliche Anwendung ist die Abkürzung von normalen SELECT-Befehlen mit Tabellen:
SELECT verleihe.* WHERE verleihe.name = 'Westward'; vid | name -----+---------- 108 | Westward
Das funktioniert, weil jede Tabelle, die in anderen Teilen des SELECT-Befehls verwendet wird, aber nicht in der FROM-Klausel erwähnt wird, implizit in die FROM-Klausel eingetragen wird.
Obwohl diese Abkürzung bequem ist, ist es einfach, sie falsch zu verwenden. Zum Beispiel ist der Befehl
SELECT verleihe.* FROM verleihe v;
wahrscheinlich ein Fehler; der Benutzer hat wohl eher
SELECT v.* FROM verleihe v;
gemeint, statt dem bedingungslosen Verbund
SELECT verleihe.* FROM verleihe v, verleihe verleihe;
der in Wirklichkeit ausgeführt wird. Um bei der Aufdeckung von dieser Art von Fehlern zu helfen, warnt PostgreSQL, wenn Elemente implizit in die FROM-Klausel eingefügt werden, obwohl der SELECT-Befehl schon eine explizite FROM-Klausel enthält.
Im SQL-Standard ist das optionale Schlüsselwort AS ohne Bedeutung und kann weggelassen werden. Der PostgreSQL-Parser erfordert dieses Schlüsselwort, wenn Ausgabespalten umbenannt werden, weil die Typenerweiterbarkeit sonst zu Syntaxkonflikten führen würde. In der FROM-Klausel ist AS jedoch optional.
Im SQL-Standard kann die ORDER BY-Klausel nur Namen oder Nummern von Ergebnisspalten verwenden, und die GROUP BY-Klausel kann nur Ausdrücke mit den Namen von Eingabespalten verwenden. PostgreSQL erweitert diese Klauseln, indem die jeweils andere Möglichkeit auch verwendet werden kann (aber der Standard geht vor, wenn es Zweideutigkeiten gibt). In PostgreSQL können in beiden Klauseln auch beliebige Ausdrücke verwendet werden. Beachten Sie, dass Namen, die in Ausdrücken verwendet werden, immer als Eingabespalten und nie als Ausgabespalten interpretiert werden.
| Zurück | Zum Anfang | Nach vorne |
| ROLLBACK | Nach oben | SELECT INTO |