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
, ... [FROMtable_references
[WHEREwhere_condition
] [GROUP BY {col_name
|expr
|position
} [ASC | DESC], ... [WITH ROLLUP]] [HAVINGwhere_condition
] [ORDER BY {col_name
|expr
|position
} [ASC | DESC], ...] [LIMIT {[offset
,]row_count
|row_count
OFFSEToffset
}] [PROCEDUREprocedure_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_name
GROUP 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_references
JOIN
“. 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_name
tbl_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_name
FROMtbl_name
HAVINGcol_name
> 0;
Formulieren Sie stattdessen wie folgt:
SELECTcol_name
FROMtbl_name
WHEREcol_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_count
LIMIT 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.