MySQL
WÄHLEN
Suche…
Einführung
SELECT
wird verwendet, um aus einer oder mehreren Tabellen ausgewählte Zeilen abzurufen.
Syntax
SELECT DISTINCT [Ausdrücke] FROM TableName [WHERE-Bedingungen]; /// Einfache Auswahl
SELECT DISTINCT (a), b ... ist das gleiche wie SELECT DISTINCT a, b ...
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] Ausdrücke FROM Tabellen [WHERE-Bedingungen] [GROUP BY-Ausdrücke] [HAVING-Bedingung] [ORDER BY-Ausdruck [ASC | DESC]] [LIMIT [offset_value] number_rows | LIMIT number_rows OFFSET offset_value] [PROCEDURE Prozedurname] [INTO [Optionen für OUTFILE 'Dateiname' | DUMPFILE 'Dateiname' | @ variable1, @ variable2, ... @variable_n] [FOR UPDATE | LOCK IN SHARE-MODUS]; /// Full Select-Syntax
Bemerkungen
Weitere Informationen zur SELECT
Anweisung von MySQL finden Sie in MySQL Docs .
SELECT nach Spaltennamen
CREATE TABLE stack(
id INT,
username VARCHAR(30) NOT NULL,
password VARCHAR(30) NOT NULL
);
INSERT INTO stack (`id`, `username`, `password`) VALUES (1, 'Foo', 'hiddenGem');
INSERT INTO stack (`id`, `username`, `password`) VALUES (2, 'Baa', 'verySecret');
Abfrage
SELECT id FROM stack;
Ergebnis
+------+
| id |
+------+
| 1 |
| 2 |
+------+
SELECT alle Spalten (*)
Abfrage
SELECT * FROM stack;
Ergebnis
+------+----------+----------+
| id | username | password |
+------+----------+----------+
| 1 | admin | admin |
| 2 | stack | stack |
+------+----------+----------+
2 rows in set (0.00 sec)
Sie können alle Spalten aus einer Tabelle in einem Join auswählen, indem Sie Folgendes tun:
SELECT stack.* FROM stack JOIN Overflow ON stack.id = Overflow.id;
Bewährtes Verfahren Verwenden Sie *
nicht, wenn Sie die Zeile (n) nicht in assoziativen Arrays debuggen oder abrufen. Andernfalls können Schemaänderungen (ADD / DROP / neu anordnen) zu bösen Anwendungsfehlern führen. Wenn Sie die Liste der Spalten angeben, die Sie in Ihrer Ergebnismenge benötigen, kann der Abfrageplaner von MySQL die Abfrage häufig optimieren.
Pros:
- Wenn Sie Spalten hinzufügen oder entfernen, müssen Sie keine Änderungen an den
SELECT *
vornehmen, an denen SieSELECT *
- Es ist kürzer zu schreiben
- Sie sehen auch die Antworten, kann
SELECT *
-Anwendung jemals gerechtfertigt sein?
Nachteile:
- Sie geben mehr Daten zurück, als Sie benötigen. Angenommen, Sie fügen eine VARBINARY-Spalte hinzu, die 200.000 Zeilen pro Zeile enthält. Sie benötigen diese Daten nur an einem Ort für einen einzelnen Datensatz. Mit
SELECT *
Sie 2 MB pro 10 Zeilen zurückgeben, die Sie nicht benötigen - Explizit darüber, welche Daten verwendet werden
- Wenn Sie Spalten angeben, erhalten Sie einen Fehler, wenn eine Spalte entfernt wird
- Der Abfrageprozessor muss etwas mehr Arbeit erledigen - herausfinden, welche Spalten in der Tabelle vorhanden sind (danke @vinodadhikary)
- Sie können leichter finden, wo eine Spalte verwendet wird
- Sie erhalten alle Spalten in Joins, wenn Sie SELECT * verwenden.
- Sie können die Ordinalreferenzierung nicht sicher verwenden (obwohl die Verwendung von Ordinalreferenzen für Spalten an sich eine schlechte Praxis ist)
- Bei komplexen Abfragen mit
TEXT
Feldern kann die Abfrage durch die weniger optimale Verarbeitung der temporären Tabelle verlangsamt werden
Wähle mit WO
Abfrage
SELECT * FROM stack WHERE username = "admin" AND password = "admin";
Ergebnis
+------+----------+----------+
| id | username | password |
+------+----------+----------+
| 1 | admin | admin |
+------+----------+----------+
1 row in set (0.00 sec)
Abfrage mit einem verschachtelten SELECT in der WHERE-Klausel
Die WHERE
Klausel kann eine beliebige gültige SELECT
Anweisung enthalten, um komplexere Abfragen zu schreiben. Dies ist eine "verschachtelte" Abfrage
Abfrage
Verschachtelte Abfragen werden normalerweise verwendet, um einzelne atomare Werte aus Abfragen für Vergleiche zurückzugeben.
SELECT title FROM books WHERE author_id = (SELECT id FROM authors WHERE last_name = 'Bar' AND first_name = 'Foo');
Wählt alle Benutzernamen ohne E-Mail-Adresse aus
SELECT * FROM stack WHERE username IN (SELECT username FROM signups WHERE email IS NULL);
Haftungsausschluss: Erwägen Sie die Verwendung von Joins für Leistungsverbesserungen, wenn Sie eine gesamte Ergebnismenge vergleichen.
WÄHLEN mit LIKE (%)
CREATE TABLE stack
( id int AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(100) NOT NULL
);
INSERT stack(username) VALUES
('admin'),('k admin'),('adm'),('a adm b'),('b XadmY c'), ('adm now'), ('not here');
"adm" überall:
SELECT * FROM stack WHERE username LIKE "%adm%";
+----+-----------+
| id | username |
+----+-----------+
| 1 | admin |
| 2 | k admin |
| 3 | adm |
| 4 | a adm b |
| 5 | b XadmY c |
| 6 | adm now |
+----+-----------+
Beginnt mit "adm":
SELECT * FROM stack WHERE username LIKE "adm%";
+----+----------+
| id | username |
+----+----------+
| 1 | admin |
| 3 | adm |
| 6 | adm now |
+----+----------+
Endet mit "adm":
SELECT * FROM stack WHERE username LIKE "%adm";
+----+----------+
| id | username |
+----+----------+
| 3 | adm |
+----+----------+
So wie das Zeichen %
in einer LIKE
Klausel einer beliebigen Anzahl von Zeichen entspricht, entspricht das Zeichen _
nur einem Zeichen. Zum Beispiel,
SELECT * FROM stack WHERE username LIKE "adm_n";
+----+----------+
| id | username |
+----+----------+
| 1 | admin |
+----+----------+
Leistungshinweise Wenn es einen Index für den username
, dann
-
LIKE 'adm'
führt das gleiche wie `= 'adm' durch -
LIKE 'adm%
ist ein "Bereich", ähnlich wie beiBETWEEN..AND..
Es kann ein Index für die Spalte verwendet werden. -
LIKE '%adm'
(oder eine Variante mit einem führenden Platzhalter) kann keinen Index verwenden. Deshalb wird es langsam sein. Bei Tabellen mit vielen Zeilen ist es wahrscheinlich so langsam, dass es unbrauchbar ist. -
RLIKE
(REGEXP
) ist tendenziell langsamer alsLIKE
, verfügt jedoch über mehr Funktionen. - Während MySQL die
FULLTEXT
Indizierung für viele Arten von Tabellen und SpaltenFULLTEXT
, werden dieseFULLTEXT
Indizes nicht zur Ausführung von Abfragen mitLIKE
.
SELECT mit Alias (AS)
SQL-Aliase werden verwendet, um eine Tabelle oder eine Spalte vorübergehend umzubenennen. Sie werden im Allgemeinen zur Verbesserung der Lesbarkeit verwendet.
Abfrage
SELECT username AS val FROM stack;
SELECT username val FROM stack;
(Hinweis: AS
ist syntaktisch optional.)
Ergebnis
+-------+
| val |
+-------+
| admin |
| stack |
+-------+
2 rows in set (0.00 sec)
SELECT mit einer LIMIT-Klausel
Abfrage:
SELECT *
FROM Customers
ORDER BY CustomerID
LIMIT 3;
Ergebnis:
Kundennummer | Kundenname | Kontaktname | Adresse | Stadt | Postleitzahl | Land |
---|---|---|---|---|---|---|
1 | Alfreds Futterkiste | Maria Anders | Obere Str. 57 | Berlin | 12209 | Deutschland |
2 | Ana Trujillo Emparedados und Helados | Ana Trujillo | Avda. de la Constitución 2222 | Mexiko df | 05021 | Mexiko |
3 | Antonio Moreno Taquería | Antonio Moreno | Mataderos 2312 | Mexiko df | 05023 | Mexiko |
Best Practice Verwenden Sie immer ORDER BY
wenn Sie LIMIT
. Andernfalls sind die Zeilen, die Sie erhalten, unvorhersehbar.
Abfrage:
SELECT *
FROM Customers
ORDER BY CustomerID
LIMIT 2,1;
Erläuterung:
Wenn eine LIMIT
Klausel zwei Zahlen enthält, wird sie als LIMIT offset,count
interpretiert LIMIT offset,count
. In diesem Beispiel überspringt die Abfrage also zwei Datensätze und gibt einen zurück.
Ergebnis:
Kundennummer | Kundenname | Kontaktname | Adresse | Stadt | Postleitzahl | Land |
---|---|---|---|---|---|---|
3 | Antonio Moreno Taquería | Antonio Moreno | Mataderos 2312 | Mexiko df | 05023 | Mexiko |
Hinweis:
Die Werte in LIMIT
Klauseln müssen Konstanten sein. Sie dürfen keine Spaltenwerte sein.
Wähle mit DISTINCT
Die DISTINCT
Klausel nach SELECT
doppelte Zeilen aus der Ergebnismenge.
CREATE TABLE `car`
( `car_id` INT UNSIGNED NOT NULL PRIMARY KEY,
`name` VARCHAR(20),
`price` DECIMAL(8,2)
);
INSERT INTO CAR (`car_id`, `name`, `price`) VALUES (1, 'Audi A1', '20000');
INSERT INTO CAR (`car_id`, `name`, `price`) VALUES (2, 'Audi A1', '15000');
INSERT INTO CAR (`car_id`, `name`, `price`) VALUES (3, 'Audi A2', '40000');
INSERT INTO CAR (`car_id`, `name`, `price`) VALUES (4, 'Audi A2', '40000');
SELECT DISTINCT `name`, `price` FROM CAR;
+---------+----------+
| name | price |
+---------+----------+
| Audi A1 | 20000.00 |
| Audi A1 | 15000.00 |
| Audi A2 | 40000.00 |
+---------+----------+
DISTINCT
arbeitet für alle Spalten, um die Ergebnisse zu liefern, nicht für einzelne Spalten. Letzteres ist oft ein Missverständnis neuer SQL-Entwickler. Kurz gesagt, es kommt auf die Unterscheidbarkeit auf Zeilenebene der Ergebnismenge an, nicht auf Unterscheidbarkeit auf Spaltenebene. Um dies zu visualisieren, schauen Sie sich "Audi A1" in der obigen Ergebnisliste an.
Für spätere Versionen von MySQL hat DISTINCT
neben ORDER BY
Auswirkungen auf seine Verwendung. Die Einstellung für ONLY_FULL_GROUP_BY
kommt ins Spiel, wie auf der folgenden MySQL-Handbuchseite mit dem Titel MySQL-Handling von GROUP BY dargestellt .
WÄHLEN mit LIKE (_)
Ein _
Zeichen in einem LIKE
Klauselmuster entspricht einem einzelnen Zeichen.
Abfrage
SELECT username FROM users WHERE users LIKE 'admin_';
Ergebnis
+----------+
| username |
+----------+
| admin1 |
| admin2 |
| admin- |
| adminA |
+----------+
SELECT mit CASE oder IF
Abfrage
SELECT st.name,
st.percentage,
CASE WHEN st.percentage >= 35 THEN 'Pass' ELSE 'Fail' END AS `Remark`
FROM student AS st ;
Ergebnis
+--------------------------------+
| name | percentage | Remark |
+--------------------------------+
| Isha | 67 | Pass |
| Rucha | 28 | Fail |
| Het | 35 | Pass |
| Ansh | 92 | Pass |
+--------------------------------+
Oder mit IF
SELECT st.name,
st.percentage,
IF(st.percentage >= 35, 'Pass', 'Fail') AS `Remark`
FROM student AS st ;
NB
IF(st.percentage >= 35, 'Pass', 'Fail')
Das bedeutet: Wenn st.percentage> = 35 TRUE ist, dann
'Pass'
ELSE'Fail'
Wähle mit ZWISCHEN
Sie können die Klausel BETWEEN verwenden, um eine Kombination der Bedingungen "größer als gleich UND kleiner als gleich" zu ersetzen.
Daten
+----+-----------+
| id | username |
+----+-----------+
| 1 | admin |
| 2 | root |
| 3 | toor |
| 4 | mysql |
| 5 | thanks |
| 6 | java |
+----+-----------+
Abfrage mit Operatoren
SELECT * FROM stack WHERE id >= 2 and id <= 5;
Ähnliche Abfrage mit BETWEEN
SELECT * FROM stack WHERE id BETWEEN 2 and 5;
Ergebnis
+----+-----------+
| id | username |
+----+-----------+
| 2 | root |
| 3 | toor |
| 4 | mysql |
| 5 | thanks |
+----+-----------+
4 rows in set (0.00 sec)
Hinweis
BETWEEN verwendet
>=
und<=
, nicht>
und<
.
Verwenden Sie NICHT ZWISCHEN
Wenn Sie das Negativ verwenden möchten, können Sie NOT
. Zum Beispiel :
SELECT * FROM stack WHERE id NOT BETWEEN 2 and 5;
Ergebnis
+----+-----------+
| id | username |
+----+-----------+
| 1 | admin |
| 6 | java |
+----+-----------+
2 rows in set (0.00 sec)
Hinweis
NOT BETWEEN verwendet
>
und<
und nicht>=
und<=
Das heißt,WHERE id NOT BETWEEN 2 and 5
ist identisch mitWHERE (id < 2 OR id > 5)
.
Wenn Sie einen Index für eine Spalte haben, die Sie in einer BETWEEN
Suche verwenden, kann MySQL diesen Index für eine Bereichsüberprüfung verwenden.
SELECT mit Datumsbereich
SELECT ... WHERE dt >= '2017-02-01'
AND dt < '2017-02-01' + INTERVAL 1 MONTH
Sicher, das könnte man mit BETWEEN
und Aufnahme von 23:59:59
. Das Muster hat jedoch folgende Vorteile:
- Das Enddatum ist nicht vorberechnet (dies ist oft eine exakte Länge von Anfang an)
- Sie schließen nicht beide Endpunkte ein (wie bei
BETWEEN
), oder geben Sie '23: 59: 59 'ein, um dies zu vermeiden. - Es funktioniert für
DATE
,TIMESTAMP
,DATETIME
und sogar für die im Mikrosekundenbereich enthalteneDATETIME(6)
. - Es kümmert sich um Schalttage, Jahresende usw.
- Es ist indexfreundlich (so ist es
BETWEEN
).