SQL ist eine Datenbanksprache und PostgreSQL ist unsere Wahl. Oft ist das Speichern von Daten nur ein Aspekt des Prozesses. Typischerweise werden Sie bei jedem datenzentrierten Unterfangen:Daten anzeigen und lesen, Maßnahmen ergreifen oder Änderungen an den Daten vornehmen, Informationen zur Entscheidungsfindung sammeln (Analysen) oder die gespeicherten Daten in irgendeiner Form oder Weise manipulieren.
SQL besteht aus einer Kombination von Schlüsselwörtern, Befehlen und Klauseln. SQL scheint einfach zu sein. Nur ein paar 'leichte “ Befehle hier und da. Keine große Sache, oder?
Aber SQL ist mehr, als man auf den ersten Blick sieht. SQL kann Sie bei diesen 'einfachen stolpern lassen ' Abfragen.
Eine Herausforderung (auf die ich regelmäßig zurückgreifen muss) besteht darin, zu verstehen, dass sich die SQL-Ausführungsreihenfolge definitiv von der ihrer Syntax unterscheidet.
In diesem Blogbeitrag besuche ich auf hoher Ebene die wichtigsten SQL-Klauseln, wie sie für PostgreSQL gelten. Es gibt viele Dialekte von SQL, aber die Interpretation von PostgreSQL steht hier im Mittelpunkt. (Einige Merkmale jeder Klausel können sehr wohl auf andere SQL-Dialekte zutreffen.)
SQL-Klauseln bilden die Grundlage für grundlegende, häufig verwendete Befehle und Abfragen. Fortgeschrittene Abfragen und Beispiele, die Fensterfunktionen, CTEs, abgeleitete Tabellen usw. verwenden, werden in diesem Beitrag jedoch nicht behandelt.
Wie wir sehen werden, sind nicht alle Klauseln gleich. Sie arbeiten jedoch zusammen und liefern Abfrageergebnisse nahtlos (oder auch nicht).
Lassen Sie mich das klarstellen...
Ich werde im gesamten Blogbeitrag regelmäßig auf eine Ausführungsanordnung hinweisen, da sie für viele der Klauseln gilt. Aber das ist verallgemeinert.
Nach meinem Verständnis wählt und entscheidet der Optimierer meistens den besten Abfrageplan für die Ausführung.
SELECT - Die "wählerische" Klausel, die zum Abfragen der Datenbank verwendet wird
SELECT ist eine beschäftigte Klausel. Es ist überall. Wird häufiger verwendet als alle anderen Klauseln. Bestimmte Klauseln benötigen Sie möglicherweise überhaupt nicht. Bei SELECT ist dies nicht so sehr der Fall, da es sich um eine obligatorische Klausel handelt.
Die SELECT-Klausel wird normalerweise zum Abfragen der Datenbank verwendet und enthält (auf einer grundlegenden Ebene):
- Eine SELECT-Liste - Die gewünschten Datenspalten.
- die Quelldatei(en) - benannt in der FROM-Klausel. Tabellen, Ansichten, CTEs usw. Hierher kommen die Daten.
- eine optionale WHERE-Klausel, die zum Filtern von Zeilen verwendet wird, die von der FROM-Klausel bereitgestellt werden.
(Die FROM- und WHERE-Klauseln werden in ihren jeweiligen Abschnitten besprochen.)
In Wahrheit würde ich sagen, dass die SELECT-Klausel in PostgreSQL erforderlich ist, um etwas abzurufen. Aber dann gibt es den TABLE-Befehl, der alle Zeilen und Spalten einer Tabelle zurückgibt.
Dennoch gibt es eine Trennung zwischen den beiden. SELECT kann einzelne Spalten angeben, aber mit dem TABLE-Befehl werden alle Spalten zurückgegeben.
Highlights AUSWÄHLEN:
- SELECT * ist eine Kurzschreibweise und gibt alle Spalten aus der/den Datenquelle(n) zurück.
- Obwohl SELECT syntaktisch als erste Klausel benannt ist (mit Ausnahme der Abfragen, die eine WITH-Klausel verwenden:hier nicht besprochen), wird es nicht zuerst ausgeführt. Bemerkenswerterweise ist SELECT auch nicht die letzte auszuführende Klausel.
- Einem Ausdruck (oder einer beliebigen Spalte) kann mit einer Einschränkung ein Referenzname oder ALIAS in der SELECT-Klausel gegeben werden. Diese Vornamen können in ORDER BY- und GROUP BY-Klauseln verwendet werden, aber nicht in WHERE- oder HAVING-Klauseln.
- Wenn eine GROUP BY-Klausel (oder Aggregatfunktionen) in der Abfrage vorhanden ist, sollte SELECT keine nicht gruppierten Spalten benennen. Nur die Spalten in Aggregatfunktion(en) oder solche, die funktional von der/den gruppierten Spalte(n) abhängig sind.
- SELECT gibt nicht nur bestimmte Spalten zurück, sondern seine Verwendung erstreckt sich auch auf INSERT- und CREATE TABLE-Anweisungen.
- Die SELECT-Klausel ist alles andere als einfach.
Ausführliche Informationen finden Sie im Abschnitt Offizielle PostgreSQL-Dokumentation zur SELECT-Klausel.
FROM – Stellt die Datenquelle(n) für die Abfrage bereit
FROM ist meistens eine obligatorische Klausel. Ich nenne das "locker ' aufgrund des verfügbaren TABLE-Befehls (oben erwähnt), der die FROM-Klausel nicht erfordert.
Andererseits können Sie beliebige Ausdrücke ohne benannte Tabelle in einer SELECT-Abfrage auswählen. Mit TABLE ist das jedoch nicht möglich.
Hier ist ein Beispiel in psql:
learning=> SELECT 2+2;
?column?
----------
4
(1 row)
Aber mit TABLE:
learning=> TABLE 2+2;
ERROR: syntax error at or near "2"
LINE 1: TABLE 2+2;
^
Einige SQL-Dialekte erlauben sogar die Benennung einer nicht vorhandenen Tabelle, um zu vermeiden, dass keine tatsächliche Tabelle in der FROM-Klausel vorhanden ist. In PostgreSQL ist dies jedoch nicht erforderlich, wie Sie der einfachen Abfrage oben entnehmen können.
Wenn Sie jedoch abgesehen von einfachen Ausdrücken tatsächlich gespeicherte Daten zurückgeben möchten, benötigen Sie die FROM-Klausel. Ohne sie gibt es keine Daten, mit denen man überhaupt arbeiten könnte.
Daher ist FROM unbedingt erforderlich, um Tabellen abzufragen.
In Postgres werden alle benannten Tabellen in der FROM-Klausel zuerst in der Ausführungsreihenfolge, die ein kartesisches Produkt erstellt, kreuzweise verbunden (wenn keine WITH-Klausel vorhanden ist). Dies ist sinnvoll, da wir Daten benötigen, um damit zu arbeiten.
Die FROM-Dokumentation hier weist auch darauf hin, dass dieser Datensatz normalerweise über eine vorhandene WHERE-Klauselbedingung auf eine kleine Anzahl von Zeilen reduziert wird.
Die FROM-Klausel akzeptiert eine Reihe spezifischer Elemente. Hier sind nur einige (die vollständige Liste finden Sie in der unten stehenden Verknüpfungsdokumentation):
- Tabellenname (offensichtlich brauchen wir das).
- EIN BLICK.
- Eine SELECT-Anweisung (eine Unterabfrage).
- CTE-Name (WITH-Klausel).
- JOIN-Typ – falls vorhanden.
- Eine Funktion (war mir nicht bewusst. Wie cool!!!)
AUS Highlights:
- Obwohl FROM syntaktisch als zweite Klausel in einer SELECT-Abfrage aufgeführt ist, wird sie zuerst ausgeführt.
- FROM liefert (durch Laden) alle Zeilen aus allen Tabellen (real oder virtuell), die in seiner Klausel genannt werden.
- Tabellennamen können in der FROM-Klausel als Alias verwendet werden (z. B. FROM Schuh-AS s), müssen aber in der weiteren Abfrage von diesem ALIAS referenziert werden.
- FROM ist eine obligatorische Klausel beim Abfragen von Tabellen.
Ausführliche Informationen finden Sie im Abschnitt Offizielle FROM-Klausel von PostgreSQL.
WHERE - Filtert Zeilen aus der/den Datenquelle(n) basierend auf booleschen bedingten Validierungsausdrücken heraus
WHERE ist eine optionale Klausel. Wenn sie jedoch in einer Abfrage vorhanden ist, ist es ihre Pflicht, die von der FROM-Klausel bereitgestellten Datensätze zu entfernen, die ihre boolesche Bedingungsprüfung nicht bestehen.
Die WHERE-Klausel hat neben SELECT auch einen großen Nutzen mit anderen SQL-Befehlen. Nämlich DML-Befehle wie INSERT (nicht direkt, sondern über SELECT), UPDATE und DELETE.
Tatsächlich würden sich UPDATE- und DELETE-Anweisungen ohne eine WHERE-Klausel wahrscheinlich auf alle Zielzeilen auswirken. Vielleicht nicht das, was Sie beabsichtigt haben (Huch!).
Aggregatfunktionen können nicht im booleschen Bedingungsausdruck der WHERE-Klausel verwendet werden. In der Ausführungsreihenfolge ist noch keine Gruppierung erfolgt. Daher sind für die WHERE-Klausel (noch) keine Aggregate verfügbar.
Die WHERE-Auswertung basiert auf einer booleschen Prüfung mit einem der Vergleichsoperatoren. (z. B.>, <, =, <> usw.)
Die WHERE-Klausel kann nicht auf Alias-Spaltennamen zugreifen, die in der SELECT-Klausel aufgeführt sind. Denn die SELECT-Klausel ist eigentlich (nicht syntaxmäßig) nach der WHERE-Klausel ausgeführt werden, sind diese Alias-Spalten noch nicht verfügbar.
WHERE-Highlights:
- Aggregatfunktionen sind nicht zugänglich und können nicht in der booleschen Bedingungsprüfung einer WHERE-Klausel verwendet werden. (Die WHERE-Klausel ist möglicherweise für alle Zeilen verantwortlich, die für Aggregatfunktionen und Gruppierungen zur Berechnung bereitgestellt werden.)
- Spalten mit Alias in der SELECT-Klausel können nicht in der WHERE-Klausel referenziert werden.
- Die Bedingungsprüfung des booleschen Ausdrucks der WHERE-Klausel kann entweder zu folgenden Ergebnissen führen:wahr, falsch oder NULL.
- Alle Zeilen, in denen der boolesche Ausdruck der WHERE-Klausel falsch oder NULL ergibt, werden entfernt.
- Mehrere boolesche Bedingungen können in der WHERE-Klausel überprüft werden, indem die Schlüsselwörter AND oder OR genutzt werden.
Ausführliche Informationen finden Sie im Abschnitt Offizielle PostgreSQL-WHERE-Klausel.
GRUPPE NACH - Bildet Gruppen
Ist eine optionale Klausel.
Diese Klausel erstellt eine einzelne Zeile für die ausgewählten, die eine Übereinstimmung mit dem angegebenen gruppierten Spaltenwert enthält.
GROUP BY kann schwierig sein, daher halte ich es für angebracht, diese Passage aus der Dokumentation einzufügen:
„Wenn GROUP BY vorhanden ist oder irgendwelche Aggregatfunktionen vorhanden sind, dürfen die Ausdrücke der SELECT-Liste nicht auf nicht gruppierte Spalten verweisen, außer innerhalb von Aggregatfunktionen oder wenn die nicht gruppierte Spalte funktional von den gruppierten Spalten abhängig ist, da dies sonst der Fall wäre mehr als ein möglicher Wert, der für eine nicht gruppierte Spalte zurückgegeben werden kann. Eine funktionale Abhängigkeit besteht, wenn die gruppierten Spalten (oder eine Teilmenge davon) der Primärschlüssel der Tabelle sind, die die nicht gruppierte Spalte enthält."
GROUP BY-Highlights:
- Postgres ermöglicht nicht nur das Gruppieren von Spalten aus der Quelltabelle, sondern auch der in der SELECT-Spaltenliste aufgeführten. Dies unterscheidet sich geringfügig von striktem SQL.
- In bestimmten Abfragen kann GROUP BY die DISTINCT-Klausel nachahmen, indem doppelte Werte für die Spalte der SELECT-Klausel entfernt werden.
- Die Spaltenreihenfolge ist für GROUP BY irrelevant.
- Diese Spalten, auf die die GROUP BY-Klausel nicht abzielt, können nur in Aggregaten referenziert werden.
- In vielen Fällen können Sie die funktional abhängigen Spalten dieses Schlüssels nach einem PRIMARY KEY gruppieren.
- Die Gruppierung wird weiterhin für Abfragen durchgeführt, die Aggregatfunktionen verwenden, wenn keine GROUP BY-Klausel vorhanden ist.
Ausführliche Informationen finden Sie im Abschnitt zur offiziellen PostgreSQL GROUP BY-Klausel.
HAVING - Filtert GROUP BY Spalte(n) und Aggregatfunktionen
Ist eine optionale Klausel.
HAVING filtert Zeilen aus der Ergebnismenge mit einer booleschen Bedingungsprüfung, genau wie die WHERE-Klausel, außer dass es die Zeilen filtert, die durch die GROUP BY-Klausel und/oder Aggregatfunktionen gebildet werden.
HAVING-Highlights:
- Die HAVING-Klausel kann zusätzlich zu allen GROUP BY-Spalten auf die in Aggregatfunktionen (auch nicht gruppierten) benannten Spalten verweisen.
- HAVING ist für das Eliminieren von Zeilen verantwortlich, nachdem Aggregatfunktionen oder Gruppierungen angewendet wurden.
- Sie können in der HAVING-Klausel auf nicht aggregierte Spalten verweisen, obwohl dies nur sehr wenig Sinn macht.
- Obwohl die HAVING-Klausel oft in Verbindung mit der GROUP BY-Klausel verwendet wird, können Sie sie allein verwenden. Abfrageergebnisse werden nur in Aggregatfunktionen in einer einzigen Gruppe dieser Spalten zusammengefasst.
Ausführliche Informationen finden Sie im Abschnitt zur offiziellen PostgreSQL HAVING-Klausel.
ORDER BY - Ein Maß für Ordnung aus Zufälligkeit
Ist eine optionale Klausel.
Verwenden Sie ORDER BY, wenn Sie eine bestimmte Reihenfolge benötigen. Andernfalls kann (und wird) die Datenbank Ergebnisse in beliebiger Reihenfolge zurückgeben.
Auch wenn die Ergebnisse einigermaßen in Ordnung zu sein scheinen, kann dies nicht garantiert werden.
Lassen Sie sich nicht täuschen. Verwenden Sie ORDER BY.
Es gibt zwei verfügbare Bestellmuster. Entweder ASC (aufsteigend) oder DESC (absteigend), wobei ASC die Voreinstellung ist.
Wenn Ihre Ergebnismenge NULL-Werte enthalten soll, können diese auch wie folgt in der Reihenfolge verwendet werden:Die Angabe von NULLS LAST bewirkt, dass sie (NULLs) nach Nicht-NULLs sortiert werden, während die Anforderung von NULLS FIRST das Gegenteil ist.
ORDER BY-Highlights:
- Sortierungsausdruck(e) sind diejenigen, die in der SELECT-Liste der Abfrage erlaubt wären.
- PostgreSQL erlaubt Ihnen ORDER BY-Spalten, die nicht in der SELECT-Klausel vorhanden sind, wo einige SQL-Dialekte dies nicht tun.
- Abfrageergebnisse sind launisch und ähneln nicht garantiert einem Muster oder einer Reihenfolge, es sei denn, es wird eine ORDER BY-Klausel verwendet.
- ORDER BY und die LIMIT-Klausel (siehe nächster Abschnitt) lassen sich hervorragend kombinieren, um ein 'Top zu bestimmen ' Zeilen Ergebnisse gesetzt. (z. B. 5 Tage mit dem höchsten Verkauf, 5 Paar Schuhe mit den niedrigsten Verkäufen, Top-Verkäufer in diesem Quartal)
- Sie können Ergebnisse nach Spaltenpositionsnummer in der SELECT-Liste sortieren, aber die angegebene Nummer darf nicht größer sein als die Anzahl der Einträge in der SELECT-Klauselliste. Mit anderen Worten, wenn die SELECT-Klausel nur 2 Elemente enthält, erzeugt ORDER BY 3 einen Fehler.
- Jeder einzelne Ausdruck wird nur nach seiner aufgelisteten Option geordnet. (z. B. ORDER BY col_1 DESC, col_2 DESC ist nicht dasselbe wie ORDER BY col_1, col_2 DESC)
Ausführliche Informationen finden Sie im Abschnitt zur offiziellen PostgreSQL-Klausel ORDER BY.
Laden Sie noch heute das Whitepaper PostgreSQL-Verwaltung und -Automatisierung mit ClusterControl herunterErfahren Sie, was Sie wissen müssen, um PostgreSQL bereitzustellen, zu überwachen, zu verwalten und zu skalierenLaden Sie das Whitepaper herunterLIMIT - Abrufen einer bestimmten Anzahl von Zeilen aus den Abfrageergebnissen
LIMIT ist eine optionale Klausel.
LIMIT besteht eigentlich aus 2 Unterklauseln, wobei OFFSET die zweite ist.
Wenn ein Wert für den OFFSET-Teil der Klausel bereitgestellt wird, werden Ergebnissatzzeilen nach zurückgegeben Überspringen dieser Anzahl von Zeilen.
Ein wichtiger Abschnitt in der Dokumentation zu beachten:
„Der Abfrageplaner berücksichtigt LIMIT beim Generieren eines Abfrageplans, sodass Sie sehr wahrscheinlich unterschiedliche Pläne erhalten (die unterschiedliche Zeilenreihenfolgen ergeben), je nachdem, was Sie für LIMIT und OFFSET verwenden. Verwenden Sie daher unterschiedliche LIMIT/OFFSET-Werte, um unterschiedliche auszuwählen Teilmengen eines Abfrageergebnisses liefern inkonsistente Ergebnisse, es sei denn, Sie erzwingen eine vorhersehbare Ergebnisreihenfolge mit ORDER BY. Dies ist kein Fehler, sondern eine inhärente Folge der Tatsache, dass SQL nicht verspricht, die Ergebnisse einer Abfrage in einer bestimmten Reihenfolge zu liefern es sei denn, ORDER BY wird verwendet, um die Reihenfolge einzuschränken."
LIMIT-Highlights:
- LIMIT kann möglicherweise weniger Zeilen als die definierte Anzahl zurückgeben, wenn die Abfrage selbst weniger Zeilen in der Ergebnismenge erzeugt. Mit anderen Worten, es hätte keinen Einfluss auf die Anzahl der zurückgegebenen Zeilen.
- Die LIMIT ALL-Syntax ist akzeptabel und hat die gleiche Wirkung wie das Nichteinfügen einer LIMIT-Klausel.
- Obwohl 'x' Zeilen aufgrund einer OFFSET-Klausel übersprungen werden, ist dies keine 'Problemumgehung ' für jeden Leistungsgewinn, da sie immer noch für den Abfrageplan auf dem Server berechnet werden.
- OFFSET 0 ist gleichbedeutend damit, überhaupt keine OFFSET-Klausel aufzunehmen.
Ausführliche Informationen finden Sie im Abschnitt Offizielle PostgreSQL-LIMIT-Klausel.
Die Interpretation der wichtigsten SQL-Klauseln durch PostgreSQL ist ihre eigene. Unabhängig davon, wie PostgreSQL sie implementiert oder nicht, sind sie die Grundlage für SQL-Abfragen, und die Vertrautheit mit ihren individuellen Merkmalen (und Nuancen) kann den Benutzern bei der Weiterentwicklung nur zugute kommen.
Obwohl zu jeder dieser Klauseln Unmengen von Artikeln, Büchern, Dokumentationen und Blog-Beiträgen geschrieben wurden, hoffe ich, dass Sie diesen Überblick auf hoher Ebene leicht verdaulich und informativ finden.
Danke fürs Lesen.