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:

  1. Wenn Sie Spalten hinzufügen oder entfernen, müssen Sie keine Änderungen an den SELECT * vornehmen, an denen Sie SELECT *
  2. Es ist kürzer zu schreiben
  3. Sie sehen auch die Antworten, kann SELECT * -Anwendung jemals gerechtfertigt sein?

Nachteile:

  1. 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
  2. Explizit darüber, welche Daten verwendet werden
  3. Wenn Sie Spalten angeben, erhalten Sie einen Fehler, wenn eine Spalte entfernt wird
  4. Der Abfrageprozessor muss etwas mehr Arbeit erledigen - herausfinden, welche Spalten in der Tabelle vorhanden sind (danke @vinodadhikary)
  5. Sie können leichter finden, wo eine Spalte verwendet wird
  6. Sie erhalten alle Spalten in Joins, wenn Sie SELECT * verwenden.
  7. Sie können die Ordinalreferenzierung nicht sicher verwenden (obwohl die Verwendung von Ordinalreferenzen für Spalten an sich eine schlechte Praxis ist)
  8. 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 bei BETWEEN..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 als LIKE , verfügt jedoch über mehr Funktionen.
  • Während MySQL die FULLTEXT Indizierung für viele Arten von Tabellen und Spalten FULLTEXT , werden diese FULLTEXT Indizes nicht zur Ausführung von Abfragen mit LIKE .

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 mit WHERE (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 enthaltene DATETIME(6) .
  • Es kümmert sich um Schalttage, Jahresende usw.
  • Es ist indexfreundlich (so ist es BETWEEN ).


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow