SELECT
[ALL | DISTINCT | DISTINCTROW ]
[HIGH_PRIORITY]
[STRAIGHT_JOIN]
[SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
[SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]
select_expr, ...
[FROM table_references
[WHERE where_condition]
[GROUP BY {col_name | expr | position}
[ASC | DESC], ... [WITH ROLLUP]]
[HAVING where_condition]
[ORDER BY {col_name | expr | position}
[ASC | DESC], ...]
[LIMIT {[offset,] row_count | row_count OFFSET offset}]
[PROCEDURE procedure_name(argument_list)]
[INTO OUTFILE 'file_name' export_options
| INTO DUMPFILE 'file_name']
[FOR UPDATE | LOCK IN SHARE MODE]]
SELECT wird zum Abrufen von Datensätzen
verwendet, die aus einer oder mehreren Tabellen ausgewählt
wurden, und kann UNION-Anweisungen und
Unterabfragen enthalten. Siehe auch Abschnitt 13.2.7.2, „UNION“, und
Abschnitt 13.2.8, „Syntax von Unterabfragen“.
Die meistverwendeten Klauseln für SELECT
sind die folgenden:
Jede select_expr gibt eine Spalte
an, die Sie abrufen wollen. Es muss mindestens ein
select_expr vorhanden sein.
table_references gibt die
Tabelle(n) an, aus der oder denen die Datensätze abgerufen
werden sollen. Die Syntax ist in Abschnitt 13.2.7.1, „JOIN“,
beschrieben.
Die WHERE-Klausel gibt, soweit vorhanden,
die Bedingung(en) an, die Datensätze erfüllen müssen,
damit sie ausgewählt werden.
where_condition ist ein Ausdruck,
der für jeden auszuwählenden Datensatz wahr ist. Die
Anweisung wählt, wenn keine
WHERE-Klausel vorhanden ist, alle
Datensätze aus.
Sie können in der WHERE-Klausel alle von
MySQL unterstützten Funktionen und Operatoren mit Ausnahme
der Zusammenfassungsfunktionen einsetzen. Siehe auch
Kapitel 12, Funktionen für die Benutzung in SELECT- und
WHERE-Klauseln.
SELECT kann auch verwendet werden, um
Datensätze abzurufen, die ohne Referenzierung einer Tabelle
berechnet wurden.
Zum Beispiel:
mysql> SELECT 1 + 1;
-> 2
Sie können DUAL als Pseudotabellenname in
Situationen angeben, in denen keine Tabellen referenziert
werden:
mysql> SELECT 1 + 1 FROM DUAL;
-> 2
DUAL ist ausschließlich zum Zweck der
Kompatibilität mit anderen Datenbankservern vorhanden, die eine
FROM-Klausel erfordern. MySQL benötigt keine
solche Klausel, wenn keine Tabellen referenziert werden.
Generell müssen Klauseln in genau der Reihenfolge angegeben
werden, die in der Syntaxbeschreibung erscheint. So muss etwa
eine HAVING-Klausel hinter den GROUP
BY-Klauseln und vor den ORDER
BY-Klauseln stehen. Die einzige Ausnahme ist die
INTO-Klausel, die entweder wie in der
Syntaxbeschreibung gezeigt oder unmittelbar vor der
FROM-Klausel stehen kann.
Einem Ausdruck select_expr lässt
sich mit AS
ein Alias
zuweisen. Der Alias wird als Spaltenname des Ausdrucks
benutzt und kann in alias_nameGROUP BY-,
ORDER BY- oder
HAVING-Klauseln verwendet werden. Zum
Beispiel:
SELECT CONCAT(last_name,', ',first_name) AS full_name FROM mytable ORDER BY full_name;
Das Schlüsselwort AS ist beim Zuweisen
eines Alias zu select_expr
optional. Das obige Beispiel hätte auch wie folgt
geschrieben sein können:
SELECT CONCAT(last_name,', ',first_name) full_name FROM mytable ORDER BY full_name;
Allerdings kann, weil AS optional ist,
ein kleines Problem auftreten, wenn Sie das Komma zwischen
zwei select_expr-Ausdrücken
vergessen: MySQL interpretiert den zweiten Ausdruck als
Aliasnamen. Sie wird etwa in der folgenden Anweisung
columnb als Aliasname behandelt:
SELECT columna columnb FROM mytable;
Aus diesem Grund hat es sich bewährt, AS
beim Festlegen von Spaltenaliasen immer explizit anzugeben.
Es ist nicht zulässig, einen Spaltenalias in einer
WHERE-Klausel zu verwenden, weil der
Spaltenwert unter Umständen nicht bestimmt werden kann,
wenn die WHERE-Klausel ausgeführt wird.
Siehe auch Abschnitt A.5.4, „Probleme mit alias“.
Die Klausel FROM
gibt
die Tabelle(n) an, aus der oder denen die Datensätze
abgerufen werden sollen. Wenn Sie mehr als eine Tabelle
angeben, führen Sie einen Join durch. Informationen zur
Join-Syntax finden Sie in Abschnitt 13.2.7.1, „table_referencesJOIN“. Für jede
angegebene Tabelle können Sie optional einen Alias angeben.
tbl_name[[AS]alias] [{USE|IGNORE|FORCE} INDEX (key_list)]
Wie Sie dem Optimierer mit USE INDEX,
IGNORE INDEX und FORCE
INDEX Hinweise zur Auswahl der Indizes geben, ist
in Abschnitt 13.2.7.1, „JOIN“, beschrieben.
Sie können SET
max_seeks_for_key=
als alternative Möglichkeit verwenden, um MySQL zur
Verwendung von Schlüssel- statt Tabellenscans (sofern
möglich) zu zwingen. Siehe auch
Abschnitt 5.2.2, „Server-Systemvariablen“.
value
Sie können eine Tabelle in der Standarddatenbank als
tbl_name oder – wenn Sie eine
Datenbank ausdrücklich angeben wollen – als
db_name.tbl_name
referenzieren. Eine Spalte können Sie als
col_name,
tbl_name.col_name
oder
db_name.tbl_name.col_name
referenzieren. Sie müssen das Präfix
tbl_name oder
db_name.tbl_name
für eine Spaltenreferenzierung nicht angeben, sofern die
Referenzierung eindeutig ist. Beispiele für
Mehrdeutigkeiten, die die spezifischeren Formen der
Spaltenreferenzierung erfordern, finden Sie in
Abschnitt 9.2, „Datenbank-, Tabellen-, Index-, Spalten- und Aliasnamen“.
Für einen Tabellenverweis kann mit
oder
tbl_name AS
alias_nametbl_name alias_name ein Alias
erstellt werden:
SELECT t1.name, t2.salary FROM employee AS t1, info AS t2 WHERE t1.name = t2.name; SELECT t1.name, t2.salary FROM employee t1, info t2 WHERE t1.name = t2.name;
Spalten, die für die Ausgabe ausgewählt werden, lassen
sich in ORDER BY- und GROUP
BY-Klauseln als Spaltennamen, Spaltenaliase oder
Spaltenpositionen referenzieren. Spaltenpositionen sind
ganze Zahlen, die bei 1 beginnen:
SELECT college, region, seed FROM tournament ORDER BY region, seed; SELECT college, region AS r, seed AS s FROM tournament ORDER BY r, s; SELECT college, region, seed FROM tournament ORDER BY 2, 3;
Um in umgekehrter (absteigender) Reihenfolge zu sortieren,
fügen Sie in der ORDER BY-Klausel das
Schlüsselwort DESC zum Namen der Spalte
zu, nach der die Sortierung erfolgt: Standardmäßig erfolgt
die Sortierung aufsteigend. Dies kann mit dem Schlüsselwort
ASC explizit festgelegt werden.
Die Verwendung von Spaltenpositionen ist veraltet, weil die Syntax im SQL-Standard nicht mehr vorhanden ist.
Wenn Sie GROUP BY verwenden, werden die
Ausgabedatensätze entsprechend den GROUP
BY-Spalten sortiert, so als ob Sie eine
ORDER BY-Klausel für dieselben Spalten
angegeben hätten. Um eine Mehrbelastung durch das Sortieren
mit GROUP BY zu vermeiden, fügen Sie
ORDER BY NULL hinzu:
SELECT a, COUNT(b) FROM test_table GROUP BY a ORDER BY NULL;
MySQL erweitert die GROUP BY-Klausel
dahingehend, dass Sie ASC und
DESC auch nach den in der Klausel
benannten Spalten angeben können:
SELECT a, COUNT(b) FROM test_table GROUP BY a DESC;
MySQL erweitert die Verwendung von GROUP
BY so, dass die Auswahl von Feldern möglich ist,
die in der GROUP BY-Klausel nicht genannt
sind. Wenn Sie bei einer Abfrage nicht die erwarteten
Ergebnisse erhalten, lesen Sie bitte die Beschreibung von
GROUP BY in
Abschnitt 12.11, „Funktionen und Modifizierer für die Verwendung in GROUP
BY-Klauseln“.
GROUP BY unterstützt den Modifizierer
WITH ROLLUP. Siehe auch
Abschnitt 12.11.2, „GROUP BY-Modifizierer“.
Die HAVING-Klausel wird fast als Letztes
angewandt – unmittelbar bevor die Elemente an den Client
gesendet werden, und ohne Optimierung. (Nur
LIMIT wird noch nach
HAVING angewandt.)
Der SQL-Standard sieht vor, dass HAVING
nur Spalten in der GROUP BY-Klausel oder
solche Spalten referenzieren darf, die in
Zusammenfassungsfunktionen verwendet werden. Allerdings
unterstützt MySQL eine Erweiterung dieses Verhaltens und
gestattet HAVING ferner die
Referenzierung von Spalten in der
SELECT-Liste und Spalten in äußeren
Unterabfragen.
Wenn die HAVING-Klausel eine Spalte
referenziert, die mehrdeutig ist, erscheint eine Warnung. In
der folgenden Anweisung ist col2
mehrdeutig, weil es sowohl als Alias als auch als
Spaltenname verwendet wird:
SELECT COUNT(col1) AS col2 FROM t GROUP BY col2 HAVING col2 = 2;
Hier wird das SQL-Standardverhalten angewandt, d. h., wenn
ein HAVING-Spaltenname sowohl in einer
GROUP BY-Klausel als auch als
Spaltenalias in der Liste der Ausgabespalten enthalten ist,
hat die Spalte in der GROUP BY-Spalte
Vorrang.
Verwenden Sie HAVING nicht für Elemente,
die in der WHERE-Klausel aufgeführt sein
sollten. So sollten Sie beispielsweise nicht Folgendes
schreiben:
SELECTcol_nameFROMtbl_nameHAVINGcol_name> 0;
Formulieren Sie stattdessen wie folgt:
SELECTcol_nameFROMtbl_nameWHEREcol_name> 0;
Die HAVING-Klausel kann
Zusammenfassungsfunktionen referenzieren, was der
WHERE-Klausel nicht möglich ist:
SELECT user, MAX(salary) FROM users GROUP BY user HAVING MAX(salary) > 10;
(Dies funktionierte bei einigen älteren MySQL-Versionen nicht.)
Die LIMIT-Klausel kann zur Beschränkung
der Anzahl der von der SELECT-Anweisung
zurückgegebenen Datensätze verwendet werden.
LIMIT nimmt ein oder zwei numerische
Argumente entgegen, die (außer bei Verwendung vorbereiteter
Anweisungen) beide nichtnegative Integer-Konstanten sein
müssen.
Von den beiden Argumenten gibt das erste den Versatz des ersten zurückzugebenden Datensatzes an, das zweite die maximale Anzahl zurückzugebender Datensätze. Der Versatz des ersten Datensatzes ist 0 (nicht 1):
SELECT * FROM tbl LIMIT 5,10; # Retrieve rows 6-15
Um alle Datensätze beginnend bei einem bestimmten Versatz bis zum Ende der Ergebnismenge zurückzugeben, können Sie als zweiten Parameter eine sehr große Zahl angeben. Die folgende Anweisung ruft alle Datensätze beginnend beim 96. bis zum letzten Datensatz ab:
SELECT * FROM tbl LIMIT 95,18446744073709551615;
Sofern nur ein Argument angegeben ist, gibt der Wert die Anzahl der Datensätze an, die beginnend beim ersten Datensatz zurückgegeben werden sollen:
SELECT * FROM tbl LIMIT 5; # Retrieve first 5 rows
Anders gesagt, ist LIMIT
äquivalent
zu row_countLIMIT 0,
.
row_count
Bei vorbereiteten Anweisungen können Sie Platzhalter
verwenden. Die folgende Anweisung gibt genau einen Datensatz
aus der Tabelle tbl zurück:
SET @a=1; PREPARE STMT FROM 'SELECT * FROM tbl LIMIT ?'; EXECUTE STMT USING @a;
Die folgenden Anweisungen geben den zweiten bis sechsten
Datensatz aus der Tabelle tbl zurück:
SET @skip=1; SET @numrows=5; PREPARE STMT FROM 'SELECT * FROM tbl LIMIT ?, ?'; EXECUTE STMT USING @skip, @numrows;
Aus Gründen der Kompatibilität mit PostgreSQL unterstützt
MySQL auch die Syntax LIMIT
.
row_count OFFSET
offset
Die Form SELECT ... INTO OUTFILE
' der
file_name'SELECT-Anweisung schreibt die
ausgewählten Datensätze in eine Datei. Die Datei wird auf
dem Serverhost erstellt, d. h., Sie benötigen die
Berechtigung FILE, um die Syntax
verwenden zu können. file_name
darf keine vorhandene Datei sein, wodurch u. a. verhindert
werden soll, dass Dateien wie
/etc/passwd und Datenbanktabellen
zerstört werden.
Die Anweisung SELECT ... INTO OUTFILE ist
in erster Linie dazu vorgesehen, eine Tabelle sehr schnell
in eine Textdatei auf dem Server zu speichern. Wenn Sie die
resultierende Datei auf einem Clienthost statt auf dem
Serverhost erstellen wollen, dürfen Sie SELECT ...
INTO OUTFILE nicht verwenden. In diesem Fall
sollten Sie stattdessen einen Befehl wie mysql -e
"SELECT ..." >
benutzen, um
die Datei auf dem Clienthost anzulegen.
file_name
SELECT ... INTO OUTFILE ist das
Gegenstück zu LOAD DATA INFILE. Die
Syntax für den
export_options-Teil der Anweisung
umfasst dieselben FIELDS- und
LINES-Klauseln, die bei LOAD
DATA INFILE benutzt werden. Siehe auch
Abschnitt 13.2.5, „LOAD DATA INFILE“.
FIELDS ESCAPED BY steuert, wie
Sonderzeichen geschrieben werden. Wenn das FIELDS
ESCAPED BY-Zeichen nicht leer ist, dann wird es
bei der Ausgabe als Präfix für die folgenden Zeichen
verwendet:
FIELDS ESCAPED BY-Zeichen
FIELDS [OPTIONALLY] ENCLOSED
BY-Zeichen
das erste Zeichen der Werte FIELDS TERMINATED
BY und LINES TERMINATED BY
ASCII NUL (das Nullwertbyte;
eigentlich wird auf das Escape-Zeichen folgend ASCII
‘0’ und kein Nullwertbyte
geschrieben)
Die FIELDS TERMINATED BY-,
ENCLOSED BY-, ESCAPED
BY- oder LINES TERMINATED
BY-Zeichen müssen mit
Escape-Zeichen gekennzeichnet werden, damit Sie die Datei
zuverlässig wiedereinlesen können. ASCII
NUL wird gekennzeichnet, um das Ablesen
bei manchen Pagern zu vereinfachen.
Die Ergebnisdatei muss nicht der SQL-Syntax entsprechen, weswegen weitere Zeichen nicht gekennzeichnet werden müssen.
Ist das FIELDS ESCAPED BY-Zeichen leer,
dann werden keinerlei Zeichen gekennzeichnet und
NULL wird als NULL
(und nicht als \N) ausgegeben. Es ist
wahrscheinlich nicht angeraten, ein leeres Escape-Zeichen
anzugeben; dies gilt insbesondere dann, wenn Feldwerte in
Ihren Daten eines der in der obigen Liste enthaltenen
Zeichen enthalten.
Es folgt ein Beispiel, das eine Datei im CSV-Format erzeugt, welches von vielen Programmen verwendet wird:
SELECT a,b,a+b INTO OUTFILE '/tmp/result.txt' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY '\n' FROM test_table;
Wenn Sie INTO DUMPFILE statt
INTO OUTFILE verwenden, schreibt MySQL
nur einen Datensatz ohne Spalten- oder Zeilentrennzeichen
und ohne Escape-Kennzeichnung in die Datei. Dies ist
praktisch, wenn Sie einen BLOB-Wert in
die Datei speichern wollen.
Hinweis: In Dateien, die
durch INTO OUTFILE oder INTO
DUMPFILE erstellt wurden, kann von allen Benutzern
geschrieben werden. Grund hierfür ist die Tatsache, dass
der MySQL Server keine Datei erstellen kann, deren Besitzer
jemand anders als der Benutzer ist, unter dessen Konto der
Server ausgeführt wird. (Sie sollten aus diesem und anderen
Gründen mysqld
niemals als root
ausführen.) Die Datei muss von allen schreibbar sein, damit
Sie ihren Inhalt modifizieren können.
Die Beschreibung der SELECT-Syntax am
Anfang dieses Abschnitts zeigt die
INTO-Klausel gegen Ende der Anweisung.
INTO OUTFILE oder INTO
DUMPFILE können auch unmittelbar auf die
FROM-Klausel folgend angegeben werden.
Eine PROCEDURE-Klausel benennt eine
Prozedur, die die Daten in der Ergebnismenge verarbeitet.
Ein Beispiel finden Sie in
Abschnitt 26.4.1, „PROCEDURE ANALYSE“.
Wenn Sie FOR UPDATE mit einer
Speicher-Engine verwenden, die Seiten- oder Datensatzsperren
verwendet, dann werden die von der Abfrage untersuchten
Datensätze bis zum Ende der laufenden Transaktion
schreibgesperrt. Mithilfe von LOCK IN SHARE
MODE wird eine gemeinsame Sperre gesetzt, die
anderen Transaktionen das Lesen, nicht jedoch das Ändern
oder Löschen der untersuchten Datensätze gestattet. Siehe
auch Abschnitt 14.2.10.5, „Lesevorgänge sperren“.
Sie können auf das Schlüsselwort SELECT
folgend eine Reihe von Optionen angeben, die den Betrieb der
Anweisung beeinflusst.
Die Optionen ALL, DISTINCT
und DISTINCTROW geben an, ob doppelte
Datensätze zurückgegeben werden sollen. Wird keine dieser
Optionen angegeben, dann wird ALL als Vorgabe
vorausgesetzt (d. h., alle passenden Datensätze werden
zurückgegeben). DISTINCT und
DISTINCTROW sind Synonyme; sie legen fest,
dass doppelte Datensätze aus der Ergebnismenge entfernt werden.
HIGH_PRIORITY,
STRAIGHT_JOIN und Optionen, die mit
SQL_ beginnen, sind MySQL-Erweiterungen zum
SQL-Standard.
HIGH_PRIORITY gibt
SELECT Vorrang vor einer Anweisung, die
eine Tabelle aktualisiert. Sie sollten die Option nur bei
Abfragen verwenden, die sehr schnell sind und sofort
erledigt werden müssen. Eine SELECT
HIGH_PRIORITY-Anweisung, die abgesetzt wird,
während die Tabelle zum Lesen gesperrt ist, wird auch
ausgeführt, wenn eine Aktualisierungsanweisung darauf
wartet, dass die Tabelle frei wird.
HIGH_PRIORITY kann nicht bei
SELECT-Anweisungen verwendet werden, die
Teil einer Union sind.
STRAIGHT_JOIN zwingt den Optimierer zur
Verknüpfung der Tabellen in der Reihenfolge, in der sie in
der FROM-Klausel angegeben sind. Sie
können hiermit eine Abfrage beschleunigen, wenn der
Optimierer die Tabellen nicht optimal anordnet. Siehe auch
Abschnitt 7.2.1, „EXPLAIN-Syntax (Informationen über ein
SELECT erhalten)“. STRAIGHT_JOIN
kann auch in der
table_references-Liste angegeben
werden. Siehe auch Abschnitt 13.2.7.1, „JOIN“.
SQL_BIG_RESULT kann mit GROUP
BY oder DISTINCT verwendet
werden. Sie teilen dem Optimierer hierdurch mit, dass die
Ergebnismenge viele Datensätze enthält. In diesem Fall
verwendet MySQL bei Bedarf direkt festplattenbasierte
Temporärtabellen und zieht die Sortierung der Verwendung
einer Temporärtabelle mit einem Schlüssel auf
GROUP BY-Elemente vor.
SQL_BUFFER_RESULT erzwingt das Ablegen
des Ergebnisses in einer Temporärtabelle. Auf diese Weise
kann MySQL die Tabellensperren schnell wieder aufheben. Die
Option ist zudem in Fällen hilfreich, in denen die
Übermittlung des Ergebnisses an den Client sehr lange
dauert.
SQL_SMALL_RESULT kann mit GROUP
BY oder DISTINCT verwendet
werden. Sie teilen dem Optimierer hierdurch mit, dass die
Ergebnismenge klein ist. In diesem Fall verwendet MySQL
schnelle Temporärtabellen zur Speicherung der
Ergebnistabelle anstelle einer Sortierung. Normalerweise
werden Sie diese Option nicht benötigen.
SQL_CALC_FOUND_ROWS weist MySQL an, zu
berechnen, wie viele Datensätze ohne Berücksichtigung
einer ggf. vorhandenen LIMIT-Klausel in
der Ergebnismenge enthalten wären. Die Anzahl der
Datensätze kann dann mit SELECT
FOUND_ROWS() abgerufen werden. Siehe auch
Abschnitt 12.10.3, „Informationsfunktionen“.
Mit SQL_CACHE weisen Sie MySQL an, das
Abfrageergebnis im Abfrage-Cache zu speichern, wenn Sie
einen query_cache_type-Wert von
2 oder DEMAND
verwenden. Bei einer Abfrage, die UNION
oder Unterabfragen verwendet, betrifft diese Option alle
SELECT-Klauseln in der Abfrage. Siehe
auch Abschnitt 5.14, „MySQL-Anfragen-Cache“.
SQL_NO_CACHE weist MySQL an, das
Abfrageergebnis nicht im Abfrage-Cache zu speichern. Siehe
auch Abschnitt 5.14, „MySQL-Anfragen-Cache“. Bei einer Abfrage, die
UNION oder Unterabfragen verwendet,
betrifft diese Option alle
SELECT-Klauseln in der Abfrage.
Dies ist eine Übersetzung des MySQL-Referenzhandbuchs, das sich auf dev.mysql.com befindet. Das ursprüngliche Referenzhandbuch ist auf Englisch, und diese Übersetzung ist nicht notwendigerweise so aktuell wie die englische Ausgabe. Das vorliegende deutschsprachige Handbuch behandelt MySQL bis zur Version 5.1.
