Die SQL -SELECT- Anweisung gibt ein Resultset von Zeilen aus einer oder mehreren Tabellen zurück . [ 1 ] [ 2 ]
Eine SELECT-Anweisung ruft null oder mehr Zeilen aus einer oder mehreren Datenbanktabellen oder -sichten ab . In den meisten Anwendungen SELECTist sie der am häufigsten verwendete Befehl der Datenmanipulationssprache (DML). Da SQL eine deklarative Programmiersprache ist , SELECTgeben Abfragen ein Ergebnis-Set an, legen aber nicht fest, wie dieses berechnet wird. Die Datenbank übersetzt die Abfrage in einen „ Abfrageplan “, der je nach Ausführung, Datenbankversion und Datenbanksoftware variieren kann. Diese Funktionalität wird als „ Abfrageoptimierer “ bezeichnet, da sie dafür verantwortlich ist, den bestmöglichen Ausführungsplan für die Abfrage unter Berücksichtigung der geltenden Einschränkungen zu finden.
Die SELECT-Anweisung enthält viele optionale Klauseln:
SELECTDie Liste enthält die Spalten oder SQL-Ausdrücke, die von der Abfrage zurückgegeben werden sollen. Dies entspricht in etwa der Projektionsoperation in der relationalen Algebra .ASOptional kann für jede Spalte oder jeden Ausdruck in derSELECTListe ein Alias angegeben werden. Dies entspricht der Umbenennungsoperation in der relationalen Algebra .FROMGibt an, aus welcher Tabelle die Daten stammen sollen. [ a ]WHEREGibt an, welche Zeilen abgerufen werden sollen. Dies entspricht in etwa der Selektionsoperation in der relationalen Algebra .GROUP BYGruppiert Zeilen mit einer gemeinsamen Eigenschaft, sodass eine Aggregatfunktion auf jede Gruppe angewendet werden kann.HAVINGWählt aus den durch die GROUP BY-Klausel definierten Gruppen aus.ORDER BYGibt an, in welcher Reihenfolge die zurückgegebenen Zeilen sortiert werden sollen.
Überblick
SELECTDie häufigste Operation in SQL ist die sogenannte „Abfrage“. SELECTSie ruft Daten aus einer oder mehreren Tabellen oder Ausdrücken ab. Standard- SELECTAbfragen haben keine dauerhaften Auswirkungen auf die Datenbank. Einige nicht standardkonforme Implementierungen SELECTkönnen jedoch dauerhafte Auswirkungen haben, wie beispielsweise die SELECT INTOin manchen Datenbanken verwendete Syntax. [ 3 ]
Abfragen ermöglichen es dem Benutzer, die gewünschten Daten zu beschreiben, während das Datenbankmanagementsystem (DBMS) die Planung , Optimierung und Durchführung der notwendigen physischen Operationen übernimmt, um dieses Ergebnis nach eigenem Ermessen zu erzielen.
Eine SQL-Abfrage enthält eine Liste der Spalten, die im Endergebnis enthalten sein sollen, normalerweise direkt nach dem SELECTSchlüsselwort. Ein Sternchen (" *") gibt an, dass die Abfrage alle Spalten aller abgefragten Tabellen zurückgeben soll. Die Abfrage SELECTist die komplexeste Anweisung in SQL und enthält optionale Schlüsselwörter und Klauseln, darunter:
- Die
FROMKlausel gibt die Tabellen an, aus denen Daten abgerufen werden sollen. DieFROMKlausel kann optionaleJOINUnterklauseln enthalten, um die Regeln für die Verknüpfung von Tabellen festzulegen. - Die
WHEREKlausel enthält ein Vergleichsprädikat, das die von der Abfrage zurückgegebenen Zeilen einschränkt. DieWHEREKlausel entfernt alle Zeilen aus dem Ergebnissatz, bei denen das Vergleichsprädikat nicht als „wahr“ ausgewertet wird. - Die
GROUP BYKlausel projiziert Zeilen mit gemeinsamen Werten in eine kleinere Menge von Zeilen.GROUP BYSie wird häufig in Verbindung mit SQL-Aggregationsfunktionen oder zum Entfernen doppelter Zeilen aus einem Ergebnissatz verwendet. DieWHEREKlausel wird vor derGROUP BYKlausel angewendet. - Die
HAVINGKlausel enthält ein Prädikat, das zum Filtern der resultierenden Zeilen dientGROUP BY. Da es auf den Ergebnissen der Klausel basiert , können im KlauselprädikatGROUP BYAggregationsfunktionen verwendet werden .HAVING - Die
ORDER BYKlausel legt fest, welche Spalten zum Sortieren der Ergebnisdaten verwendet werden und in welcher Richtung (aufsteigend oder absteigend) sortiert werden soll. Ohne eine solcheORDER BYKlausel ist die Reihenfolge der von einer SQL-Abfrage zurückgegebenen Zeilen undefiniert. - Das
DISTINCTSchlüsselwort [ 4 ] entfernt doppelte Daten. [ 5 ]
Die folgende Abfrage SELECTliefert eine Liste teurer Bücher. Sie ruft alle Zeilen aus der Tabelle „Buch“ ab , deren Preisspalte einen Wert über 100,00 enthält. Das Ergebnis ist aufsteigend nach Titel sortiert . Das Sternchen (*) in der Auswahlliste bedeutet, dass alle Spalten der Tabelle „Buch“ im Ergebnis enthalten sein sollen.
SELECT * FROM Book WHERE price > 100 . 00 ORDER BY title ;Das folgende Beispiel veranschaulicht eine Abfrage mehrerer Tabellen, Gruppierung und Aggregation, indem es eine Liste von Büchern und die Anzahl der Autoren, die mit jedem Buch verbunden sind, zurückgibt.
SELECT Book.title AS Title , count ( * ) AS Authors FROM Book JOIN Book_author ON Book.isbn = Book_author.isbn GROUP BY Book.title ;Eine Beispielausgabe könnte wie folgt aussehen:
Titel Autoren ---------------------- ------- SQL-Beispiele und Leitfaden 4 Die Freude an SQL 1 Einführung in SQL 2 Fallstricke von SQL 1
Unter der Voraussetzung, dass „isbn“ der einzige gemeinsame Spaltenname der beiden Tabellen ist und dass eine Spalte namens „ title“ nur in der Tabelle „Book“ existiert , könnte man die obige Abfrage wie folgt umschreiben:
SELECT title , count ( * ) AS Authors FROM Book NATURAL JOIN Book_author GROUP BY title ;Viele Anbieter unterstützen diesen Ansatz jedoch entweder nicht oder verlangen bestimmte Namenskonventionen für Spalten, damit natürliche Joins effektiv funktionieren.
SQL enthält Operatoren und Funktionen zur Berechnung von Werten auf Basis gespeicherter Werte. SQL ermöglicht die Verwendung von Ausdrücken in der Auswahlliste zur Datenprojektion, wie im folgenden Beispiel, das eine Liste von Büchern zurückgibt, die mehr als 100,00 kosten, mit einer zusätzlichen Spalte „sales_tax “, die die Mehrwertsteuer in Höhe von 6 % des Preises enthält .
SELECT isbn , title , price , price * 0.06 AS sales_tax FROM Book WHERE price > 100.00 ORDER BY title ;Unterabfragen
Abfragen lassen sich verschachteln, sodass die Ergebnisse einer Abfrage in einer anderen Abfrage mithilfe eines relationalen Operators oder einer Aggregationsfunktion verwendet werden können. Eine verschachtelte Abfrage wird auch als Unterabfrage bezeichnet . Obwohl Joins und andere Tabellenoperationen in vielen Fällen rechentechnisch überlegene (d. h. schnellere) Alternativen bieten (je nach Implementierung), führt die Verwendung von Unterabfragen zu einer Ausführungshierarchie, die nützlich oder sogar notwendig sein kann. Im folgenden Beispiel erhält die Aggregationsfunktion AVGals Eingabe das Ergebnis einer Unterabfrage:
SELECT isbn , title , price FROM Book WHERE price < ( SELECT AVG ( price ) FROM Book ) ORDER BY title ;Eine Unterabfrage kann Werte aus der äußeren Abfrage verwenden; in diesem Fall spricht man von einer korrelierten Unterabfrage .
Seit 1999 erlaubt der SQL-Standard WITH-Klauseln, d. h. benannte Unterabfragen, die oft als Common Table Expressions (CTEs) bezeichnet werden (benannt und entworfen nach der IBM DB2 Version 2-Implementierung; Oracle nennt dies Subquery Factoring ). CTEs können auch rekursiv sein , indem sie auf sich selbst verweisen; der resultierende Mechanismus ermöglicht Baum- oder Graphdurchläufe (wenn diese als Relationen dargestellt werden) und allgemeiner Fixpunktberechnungen .
Abgeleitete Tabelle
Eine abgeleitete Tabelle ist eine Unterabfrage in einer FROM-Klausel. Im Wesentlichen handelt es sich um eine Unterabfrage, aus der Daten ausgewählt oder mit der verknüpft werden können. Die Funktionalität abgeleiteter Tabellen ermöglicht es dem Benutzer, auf die Unterabfrage wie auf eine Tabelle zu verweisen. Die abgeleitete Tabelle wird auch als Inline-View oder SELECT-IN-FROM-Liste bezeichnet .
Im folgenden Beispiel beinhaltet die SQL-Anweisung einen Join der ursprünglichen Tabelle „Books“ mit der abgeleiteten Tabelle „Sales“. Diese abgeleitete Tabelle erfasst die zugehörigen Buchverkaufsinformationen und verwendet die ISBN, um sie mit der Tabelle „Books“ zu verknüpfen. Dadurch liefert die abgeleitete Tabelle dem Ergebnis-Set zusätzliche Spalten (die Anzahl der verkauften Exemplare und das Unternehmen, das die Bücher verkauft hat):
SELECT b.isbn , b.title , b.price , sales.items_sold , sales.company_nm FROM Book b JOIN ( SELECT SUM ( Items_Sold ) Items_Sold , Company_Nm , ISBN FROM Book_Sales GROUP BY Company_Nm , ISBN ) sales ON sales.isbn = b.isbnBeispiele
| Tabelle "T" | Abfrage | Ergebnis | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| SELECT*FROMT; |
| ||||||||||||
| SELECTC1FROMT; |
| ||||||||||||
| SELECT*FROMTWHEREC1=1; |
| ||||||||||||
| SELECT*FROMTORDERBYC1DESC; |
| ||||||||||||
| Existiert nicht | SELECT1+1,3*2; |
|
Bei gegebener Tabelle T führt die Abfrage dazu, dass alle Elemente aller Zeilen der Tabelle angezeigt werden. SELECT*FROMT
Bei derselben Tabelle liefert die Abfrage die Elemente aus Spalte C1 aller Tabellenzeilen. Dies ähnelt einer Projektion in der relationalen Algebra , mit dem Unterschied, dass das Ergebnis im Allgemeinen doppelte Zeilen enthalten kann. In der Datenbanksprache wird dies auch als vertikale Partitionierung bezeichnet, wodurch die Abfrageausgabe auf die Anzeige bestimmter Felder oder Spalten beschränkt wird. SELECTC1FROMT
Bei derselben Tabelle liefert die Abfrage alle Elemente aller Zeilen, in denen der Wert der Spalte C1 gleich '1' ist. In der relationalen Algebra spricht man von einer Selektion aufgrund der WHERE-Klausel. Dies wird auch als horizontale Partitionierung bezeichnet, da die von einer Abfrage ausgegebenen Zeilen anhand bestimmter Bedingungen eingeschränkt werden. SELECT*FROMTWHEREC1=1
Bei mehreren Tabellen umfasst das Ergebnis jede beliebige Zeilenkombination. Sind die beiden Tabellen beispielsweise T1 und T2, ergibt sich jede Kombination von Zeilen aus T1 und T2. Hat T1 beispielsweise 3 Zeilen und T2 5 Zeilen, so ergibt sich ein Ergebnis von 15 Zeilen. SELECT*FROMT1,T2
Obwohl es nicht dem Standard entspricht, erlauben die meisten DBMS die Verwendung einer SELECT-Klausel ohne Tabelle, indem sie so tun, als würde eine imaginäre Tabelle mit nur einer Zeile verwendet. Dies wird hauptsächlich für Berechnungen genutzt, bei denen keine Tabelle benötigt wird.
Die SELECT-Klausel gibt eine Liste von Eigenschaften (Spalten) anhand ihres Namens oder des Platzhalterzeichens („*“) an, um „alle Eigenschaften“ zu bezeichnen.
Ergebniszeilen einschränken
Oft ist es sinnvoll, eine maximale Anzahl der zurückzugebenden Zeilen anzugeben. Dies kann zu Testzwecken oder zur Vermeidung übermäßiger Ressourcennutzung verwendet werden, falls die Abfrage mehr Informationen als erwartet liefert. Die Vorgehensweise hierfür variiert häufig je nach Anbieter.
In ISO SQL:2003 können Ergebnismengen durch die Verwendung von
- Cursor oder
- durch Hinzufügen einer SQL-Fensterfunktion zur SELECT-Anweisung
Mit ISO SQL:2008 wurde die FETCH FIRSTKlausel eingeführt.
Laut der Dokumentation von PostgreSQL v.9 führt eine SQL-Fensterfunktion „eine Berechnung über eine Menge von Tabellenzeilen durch, die in irgendeiner Weise mit der aktuellen Zeile in Beziehung stehen“, ähnlich wie Aggregatfunktionen. [ 6 ] Der Name erinnert an Fensterfunktionen der Signalverarbeitung . Ein Aufruf einer Fensterfunktion enthält immer eine OVER- Klausel.
Fensterfunktion ROW_NUMBER()
ROW_NUMBER() OVERkann für eine einfache Tabelle der zurückgegebenen Zeilen verwendet werden , z. B. um maximal zehn Zeilen zurückzugeben:
SELECT * FROM ( SELECT ROW_NUMBER () OVER ( ORDER BY sort_key ASC ) AS row_number , columns FROM tablename ) AS foo WHERE row_number <= 10ROW_NUMBER kann nicht deterministisch sein : Wenn sort_key nicht eindeutig ist, können bei jeder Ausführung der Abfrage unterschiedliche Zeilennummern für Zeilen mit gleichem sort_key zugewiesen werden. Ist sort_key eindeutig, erhält jede Zeile immer eine eindeutige Zeilennummer.
RANK() Fensterfunktion
Die RANK() OVERFensterfunktion verhält sich wie ROW_NUMBER , kann aber im Falle von Gleichständen mehr oder weniger als n Zeilen zurückgeben, z. B. um die 10 jüngsten Personen zurückzugeben:
SELECT * FROM ( SELECT RANK () OVER ( ORDER BY age ASC ) AS ranking , person_id , person_name , age FROM person ) AS foo WHERE ranking <= 10Der obige Code könnte mehr als zehn Zeilen zurückgeben, z. B. wenn es zwei Personen gleichen Alters gibt, könnte er elf Zeilen zurückgeben.
FETCH FIRST-Klausel
Seit ISO SQL:2008 können Ergebnisgrenzen wie im folgenden Beispiel mithilfe der FETCH FIRSTKlausel angegeben werden.
SELECT * FROM T FETCH FIRST 10 ROWS ONLYMicrosoft SQL Server 2008 und höher unterstützen diesFETCH FIRST , es wird jedoch als Teil der ORDER BYKlausel betrachtet. Die Klauseln ORDER BY, OFFSET, und FETCH FIRSTsind für diese Verwendung erforderlich.
SELECT * FROM T ORDER BY acolumn DESC OFFSET 0 ROWS FETCH FIRST 10 ROWS ONLYNicht standardkonforme Syntax
Einige DBMS bieten eine nicht standardisierte Syntax an, entweder anstelle oder zusätzlich zur SQL-Standardsyntax. Im Folgenden sind Varianten der einfachen LIMIT- Abfrage für verschiedene DBMS aufgeführt:
SET ROWCOUNT 10 SELECT * FROM T | MS SQL Server (Dies funktioniert auch unter Microsoft SQL Server 6.5, während die Abfrage "Select top 10 * from T " dies nicht tut) |
SELECT * FROM T LIMIT 10 OFFSET 20 | Netezza , MySQL , MariaDB (unterstützt ab Version 10.6 auch die Standardversion), SAP SQL Anywhere , PostgreSQL (unterstützt ab Version 8.4 auch die Standardversion), SQLite , HSQLDB , H2 , Vertica , Polyhedra , Couchbase Server , Snowflake Computing , OpenLink Virtuoso |
SELECT * FROM T WHERE ROWNUM <= 10 | Orakel |
SELECT FIRST 10 * from T | Ingres |
SELECT FIRST 10 * FROM T order by a | Informix |
SELECT SKIP 20 FIRST 10 * FROM T order by c, d | Informix (Zeilennummern werden gefiltert, nachdem die ORDER BY-Klausel ausgewertet wurde. Die SKIP-Klausel wurde in einem Fixpack der Version 10.00.xC4 eingeführt.) |
SELECT TOP 10 * FROM T | MS SQL Server , SAP ASE , MS Access , SAP IQ , Teradata |
SELECT * FROM T SAMPLE 10 | Teradata |
SELECT TOP 20, 10 * FROM T | OpenLink Virtuoso (überspringt 20, liefert die nächsten 10 aus) [ 7 ] |
SELECT TOP 10 START AT 20 * FROM T | SAP SQL Anywhere (unterstützt seit Version 9.0.1 auch den Standard) |
SELECT FIRST 10 SKIP 20 * FROM T | Feuervogel |
SELECT * FROM T ROWS 20 TO 30 | Firebird (seit Version 2.1) |
SELECT * FROM T WHERE ID_T > 10 FETCH FIRST 10 ROWS ONLY | IBM Db2 |
SELECT * FROM T WHERE ID_T > 20 FETCH FIRST 10 ROWS ONLY | IBM Db2 (neue Zeilen werden nach dem Vergleich mit der Schlüsselspalte der Tabelle T gefiltert) |
Zeilen Paginierung
Die Zeilenpaginierung [ 8 ] ist ein Verfahren, mit dem nur ein Teil der Gesamtdaten einer Datenbankabfrage angezeigt wird. Anstatt Hunderte oder Tausende von Zeilen gleichzeitig anzuzeigen, wird vom Server jeweils nur eine Seite angefordert (z. B. nur 10 Zeilen). Der Benutzer navigiert dann, indem er die nächste Seite anfordert usw. Dies ist besonders in Webanwendungen nützlich, da dort keine dedizierte Verbindung zwischen Client und Server besteht und der Client somit nicht warten muss, bis alle Zeilen vom Server geladen und angezeigt wurden.
Daten im Paginierungsansatz
{rows}= Anzahl der Zeilen pro Seite{page_number}= Nummer der aktuellen Seite{begin_base_0}= Nummer der Zeile - 1, in der die Seite beginnt = (Seitennummer-1) * Zeilen
Einfachste Methode (aber sehr ineffizient)
- Alle Zeilen aus der Datenbank auswählen
- Lies alle Zeilen, zeige sie aber nur an, wenn die Zeilennummer der gelesenen Zeilen zwischen
{begin_base_0 + 1}und liegt.{begin_base_0 + rows}
SELECT * FROM { table } ORDER BY { unique_key }Eine andere einfache Methode (etwas effizienter als alle Zeilen zu lesen)
- Wählen Sie alle Zeilen vom Anfang der Tabelle bis zur letzten Zeile aus, die angezeigt werden sollen (
{begin_base_0 + rows}). - Lies die
{begin_base_0 + rows}Zeilen, zeige sie aber nur an, wenn die Zeilennummer der gelesenen Zeilen größer ist als{begin_base_0}
| SQL | Dialekt |
|---|---|
SELECT * FROM { table } ORDER BY { unique_key } FETCH FIRST { begin_base_0 + rows } ROWS ONLY | SQL ANSI 2008 PostgreSQL SQL Server 2012 Derby Oracle 12c DB2 12 Mimer SQL |
SELECT * FROM { table } ORDER BY { unique_key } LIMIT { begin_base_0 + rows } | MySQL SQLite |
SELECT TOP { begin_base_0 + rows } * FROM { table } ORDER BY { unique_key } | SQL Server 2005 |
SELECT * FROM { table } ORDER BY { unique_key } ROWS LIMIT { begin_base_0 + rows } | Sybase, ASE 16 SP2 |
SET ROWCOUNT { begin_base_0 + rows } Select * from { table } order by { unique_key } SET ROWCOUNT 0 | Sybase, SQL Server 2000 |
SELECT * FROM ( SELECT * FROM { table } ORDER BY { unique_key } ) a WHERE rownum <= { begin_base_0 + rows } | Oracle 11 |
Methode mit Positionierung
{rows}Nur die Zeilen ab der nächsten anzuzeigenden Zeile auswählen ({begin_base_0 + 1})- Lesen und senden Sie eine Funktion, um alle aus der Datenbank gelesenen Zeilen anzuzeigen.
| SQL | Dialekt |
|---|---|
SELECT * FROM { table } ORDER BY { unique_key } OFFSET { begin_base_0 } ROWS FETCH NEXT { rows } ROWS ONLY | SQL ANSI 2008 PostgreSQL SQL Server 2012 Derby Oracle 12c DB2 12 Mimer SQL |
SELECT * FROM { table } ORDER BY { unique_key } LIMIT { rows } OFFSET { begin_base_0 } | MySQL, MariaDB, PostgreSQL, SQLite |
SELECT * FROM { table } ORDER BY { unique_key } LIMIT { begin_base_0 } , { rows } | MySQL, MariaDB, SQLite |
SELECT * FROM { table } ORDER BY { unique_key } ROWS LIMIT { rows } OFFSET { begin_base_0 } | Sybase, ASE 16 SP2 |
SELECT TOP { begin_base_0 + rows } * , _offset = identity ( 10 ) INTO #temp FROM { table } ORDER BY { unique_key } SELECT * FROM #temp WHERE _offset > { begin_base_0 } DROP TABLE #temp | Sybase 12.5.3: |
SET ROWCOUNT { begin_base_0 + rows } select * , _offset = identity ( 10 ) into #temp from { table } ORDER BY { unique_key } select * from #temp where _offset > { begin_base_0 } DROP TABLE #temp SET ROWCOUNT 0 | Sybase 12.5.2: |
SELECT TOP { rows } * FROM ( SELECT * , ROW_NUMBER () OVER ( ORDER BY { unique_key } ) AS _offset FROM { table } ) xx WHERE _offset > { begin_base_0 } | SQL Server 2005 |
SET ROWCOUNT { begin_base_0 + rows } select * , _offset = identity ( int , 1 , 1 ) into #temp from { table } ORDER BY { unique - key } select * from #temp where _offset > { begin_base_0 } DROP TABLE #temp SET ROWCOUNT 0 | SQL Server 2000 |
SELECT * FROM ( SELECT rownum - 1 as _offset , a . * FROM ( SELECT * FROM { table } ORDER BY { unique_key } ) a WHERE rownum <= { begin_base_0 + cant_regs } ) WHERE _offset >= { begin_base_0 } | Oracle 11 |
Methode mit Filter (sie ist komplexer, aber für sehr große Datensätze notwendig)
- Wählen Sie nur dann
{rows}Zeilen mit Filter aus:{rows}Erste Seite: Je nach Datenbanktyp werden nur die ersten Zeilen ausgewählt .- Nächste Seite: Wählen Sie
{rows}je nach Datenbanktyp nur die ersten Zeilen aus, in denen der Wert{unique_key}größer ist als{last_val}der Wert{unique_key}der letzten Zeile auf der aktuellen Seite. - Vorherige Seite: Sortieren Sie die Daten in umgekehrter Reihenfolge, wählen Sie nur die ersten
{rows}Zeilen aus, in denen der Wert{unique_key}kleiner als{first_val}der Wert der{unique_key}ersten Zeile der aktuellen Seite ist, und sortieren Sie das Ergebnis in der richtigen Reihenfolge.
- Lesen und senden Sie eine Funktion, um alle aus der Datenbank gelesenen Zeilen anzuzeigen.
| Erste Seite | Nächste Seite | Vorherige Seite | Dialekt |
|---|---|---|---|
SELECT * FROM { table } ORDER BY { unique_key } FETCH FIRST { rows } ROWS ONLY | SELECT * FROM { table } WHERE { unique_key } > { last_val } ORDER BY { unique_key } FETCH FIRST { rows } ROWS ONLY | SELECT * FROM ( SELECT * FROM { Tabelle } WHERE { unique_key } < { first_val } ORDER BY { unique_key } DESC FETCH FIRST { rows } ROWS ONLY ) a ORDER BY { unique_key } | SQL ANSI 2008 PostgreSQL SQL Server 2012 Derby Oracle 12c DB2 12 Mimer SQL |
SELECT * FROM { table } ORDER BY { unique_key } LIMIT { rows } | SELECT * FROM { table } WHERE { unique_key } > { last_val } ORDER BY { unique_key } LIMIT { rows } | SELECT * FROM ( SELECT * FROM { Tabelle } WHERE { unique_key } < { first_val } ORDER BY { unique_key } DESC LIMIT { rows } ) a ORDER BY { unique_key } | MySQL SQLite |
SELECT TOP { rows } * FROM { table } ORDER BY { unique_key } | SELECT TOP { rows } * FROM { table } WHERE { unique_key } > { last_val } ORDER BY { unique_key } | SELECT * FROM ( SELECT TOP { ROWS } * FROM { TABLE } WHERE { UNIQUE_KEY } < { ERSTES_WERT } ORDER BY { UNIQUE_KEY } DESC ) a ORDER BY { UNIQUE_KEY } | SQL Server 2005 |
SET ROWCOUNT { rows } select * from { table } order by { unique_key } SET ROWCOUNT 0 | SET ROWCOUNT { rows } select * from { table } where { unique_key } > { last_val } order by { unique_key } SET ROWCOUNT 0 | SET ROWCOUNT { rows } select * from ( select * from { table } where { unique_key } < { first_val } order by { unique_key } DESC ) a order by { unique_key } SET ROWCOUNT 0 | Sybase, SQL Server 2000 |
SELECT * FROM ( SELECT * FROM { Tabelle } ORDER BY { unique_key } ) a WHERE rownum <= { rows } | SELECT * FROM ( SELECT * FROM { Tabelle } WHERE { unique_key } > { last_val } ORDER BY { unique_key } ) a WHERE rownum <= { rows } | SELECT * FROM ( SELECT * FROM ( SELECT * FROM { Tabelle } WHERE { unique_key } < { first_val } ORDER BY { unique_key } DESC ) a1 WHERE rownum <= { rows } ) a2 ORDER BY { unique_key } | Oracle 11 |
Hierarchische Abfrage
Manche Datenbanken bieten eine spezielle Syntax für hierarchische Daten .
Eine Fensterfunktion in SQL:2003 ist eine Aggregatfunktion, die auf eine Partition des Resultsets angewendet wird.
Zum Beispiel,
sum ( population ) OVER ( PARTITION BY city )Berechnet die Summe der Einwohnerzahlen aller Zeilen, die denselben Stadtwert wie die aktuelle Zeile haben.
Partitionen werden mithilfe der OVER- Klausel angegeben, welche die Aggregation modifiziert. Syntax:
< OVER_CLAUUSE > :: = OVER ( [ PARTITION BY < expr > , ... ] [ ORDER BY < Ausdruck > ] ) Die OVER-Klausel ermöglicht das Partitionieren und Sortieren des Ergebnissatzes. Die Sortierung wird für reihenfolgebezogene Funktionen wie z. B. row_number verwendet.
ANSI-Abfrageauswertung
Die Verarbeitung einer SELECT-Anweisung gemäß ANSI SQL würde wie folgt aussehen: [ 9 ]
SELECT g . * FROM users u INNER JOIN GROUPS g ON g.Userid = u.Userid WHERE u.LastName = ' Smith ' AND u.FirstName = ' John '
- Die FROM-Klausel wird ausgewertet, und es wird ein Cross Join oder ein kartesisches Produkt der ersten beiden Tabellen in der FROM-Klausel erstellt, was zu einer virtuellen Tabelle namens Vtable1 führt.
- Die ON-Klausel wird für Vtable1 ausgewertet; nur Datensätze, die die Join-Bedingung g.Userid = u.Userid erfüllen, werden in Vtable2 eingefügt.
- Wird ein Outer Join angegeben, werden Datensätze, die aus vTable2 entfernt wurden, in vTable3 hinzugefügt, beispielsweise wenn die obige Abfrage lautet: Alle Benutzer, die keiner Gruppe angehören, würden wieder in Vtable3 hinzugefügt.
SELECT u . * FROM users u LEFT JOIN GROUPS g ON g.Userid = u.Userid WHERE u.LastName = ' Smith ' AND u.FirstName = ' John '
- Die WHERE-Klausel wird ausgewertet; in diesem Fall würden nur die Gruppeninformationen für den Benutzer John Smith zu vTable4 hinzugefügt.
- Die GROUP BY-Klausel wird ausgewertet; wenn die obige Abfrage lautet: vTable5 würde aus den von vTable4 zurückgegebenen Elementen bestehen, die nach der Gruppierung, in diesem Fall dem Gruppennamen, geordnet sind.
SELECT g.GroupName , COUNT ( g . * ) AS NumberOfMembers FROM users u INNER JOIN groups g ON g.Userid = u.Userid GROUP BY GroupName
- Die HAVING-Klausel wird für Gruppen ausgewertet, für die die HAVING-Klausel wahr ist, und die Ergebnisse werden in vTable6 eingefügt. Zum Beispiel:
SELECT g.GroupName , COUNT ( g . * ) AS NumberOfMembers FROM users u INNER JOIN groups g ON g.Userid = u.Userid GROUP BY GroupName HAVING COUNT ( g . * ) > 5
- Die SELECT-Liste wird ausgewertet und als Vtable 7 zurückgegeben.
- Die DISTINCT-Klausel wird ausgewertet; doppelte Zeilen werden entfernt und als Vtable 8 zurückgegeben.
- Die ORDER BY-Klausel wird ausgewertet, sortiert die Zeilen und gibt VCursor9 zurück. Dies ist ein Cursor und keine Tabelle, da ANSI einen Cursor als geordnete Menge von Zeilen (nicht relational) definiert.
Unterstützung von Fensterfunktionen durch RDBMS-Anbieter
Die Implementierung von Fensterfunktionen durch Anbieter relationaler Datenbanken und SQL-Engines variiert stark. Die meisten Datenbanken unterstützen zumindest eine Variante von Fensterfunktionen. Bei genauerer Betrachtung zeigt sich jedoch, dass die meisten Anbieter nur eine Teilmenge des Standards implementieren. Nehmen wir die leistungsstarke RANGE-Klausel als Beispiel. Nur Oracle, DB2, Spark/Hive und Google BigQuery implementieren diese Funktion vollständig. In jüngster Zeit haben Anbieter den Standard um neue Erweiterungen ergänzt, z. B. Array-Aggregationsfunktionen. Diese sind besonders nützlich beim Ausführen von SQL-Abfragen auf verteilten Dateisystemen (Hadoop, Spark, Google BigQuery), wo die Datenlokalität weniger zuverlässig gewährleistet ist als bei verteilten relationalen Datenbanken (MPP). Anstatt die Daten gleichmäßig auf alle Knoten zu verteilen, können SQL-Engines, die Abfragen auf verteilten Dateisystemen ausführen, die Datenlokalität durch Verschachtelung der Daten sicherstellen und so potenziell aufwändige Joins mit umfangreichem Datenaustausch im Netzwerk vermeiden. Benutzerdefinierte Aggregatfunktionen, die in Fensterfunktionen verwendet werden können, stellen ein weiteres äußerst leistungsstarkes Feature dar.
Datengenerierung in T-SQL
Methode zur Generierung von Daten basierend auf der Vereinigung aller
SELECT 1a , 1b UNION ALL SELECT 1 , 2 UNION ALL SELECT 1 , 3 UNION ALL SELECT 2 , 1 UNION ALL SELECT 5 , 1SQL Server 2008 unterstützt die im SQL:1999- Standard spezifizierte Funktion „Zeilenkonstruktor“.
SELECT * FROM ( VALUES ( 1 , 1 ), ( 1 , 2 ), ( 1 , 3 ), ( 2 , 1 ), ( 5 , 1 )) AS x ( a , b )Anmerkungen
- ^ Das Weglassen der FROM-Klausel ist nicht Standard, wird aber von den meisten großen DBMS toleriert.
Referenzen
- ^ Microsoft (23. Mai 2023). „Transact-SQL-Syntaxkonventionen“ .
- ^ MySQL. "SQL SELECT Syntax" .
- ^ „Transact-SQL-Referenz“. SQL Server-Sprachreferenz . SQL Server 2005 Books Online. Microsoft. 15.09.2007 . Abgerufen am 17.06.2007 .
- ^ SAS 9.4 SQL Procedure User's Guide . SAS Institute (veröffentlicht 2013). 10. Juli 2013. S. 248. ISBN 9781612905686Abgerufen am 21.10.2015 .
Obwohl das UNIQUE-Argument mit DISTINCT identisch ist, handelt es sich nicht um einen ANSI-Standard.
- ^ Leon, Alexis ; Leon, Mathews (1999). „Eliminating duplicates - SELECT using DISTINCT“. SQL: A Complete Reference . New Delhi: Tata McGraw-Hill Education (erschienen 2008). S. 143. ISBN 9780074637081Abgerufen am 21.10.2015 .
[...] Das Schlüsselwort DISTINCT [...] entfernt die Duplikate aus dem Ergebnissatz.
- ^ PostgreSQL 9.1.24 Dokumentation – Kapitel 3. Erweiterte Funktionen
- ^ OpenLink Software. „9.19.10. Die TOP SELECT Option“ . docs.openlinksw.com . Abgerufen am 1. Oktober 2019 .
- ^ Ing. Óscar Bonilla, MBA
- ^ Einblick in Microsoft SQL Server 2005: T-SQL-Abfragen von Itzik Ben-Gan, Lubor Kollar und Dejan Sarka
Quellen
- Horizontale und vertikale Partitionierung, Microsoft SQL Server 2000 – Online-Dokumentation.