MySQL
SELECT
Zoeken…
Invoering
SELECT
wordt gebruikt om rijen gekozen uit een of meer tabellen op te halen.
Syntaxis
SELECTEER DISTINCT [uitdrukkingen] VAN Tabelnaam [WAAR voorwaarden]; /// Simple Select
SELECT DISTINCT (a), b ... is hetzelfde als SELECT DISTINCT a, b ...
SELECTEER [ALLES | ONDERSCHEIDEN | DISTINCTROW] [HIGH_PRIORITY] [STRAIGHT_JOIN] [SQL_SMALL_RESULT | SQL_BIG_RESULT] [SQL_BUFFER_RESULT] [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS] expressies UIT tabellen [WHERE condities] [GROUP BY expressions] [HAVING condition] [ORDER BY expression [ASC | DESC]] [LIMIT [offset_value] number_rows | LIMIT aantal rijen OFFSET offset_waarde] [PROCEDURE procedure_name] [INTO [OUTFILE 'bestandsnaam' opties | DUMPFILE 'file_name' | @ variable1, @ variable2, ... @variable_n] [VOOR UPDATE | LOCK IN DELENMODUS]; /// Volledige selectie syntaxis
Opmerkingen
Raadpleeg MySQL Docs voor meer informatie over de SELECT
instructie van MySQL .
SELECTEER op kolomnaam
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');
vraag
SELECT id FROM stack;
Resultaat
+------+
| id |
+------+
| 1 |
| 2 |
+------+
SELECTEER alle kolommen (*)
vraag
SELECT * FROM stack;
Resultaat
+------+----------+----------+
| id | username | password |
+------+----------+----------+
| 1 | admin | admin |
| 2 | stack | stack |
+------+----------+----------+
2 rows in set (0.00 sec)
U kunt alle kolommen uit één tabel in een join selecteren door het volgende te doen:
SELECT stack.* FROM stack JOIN Overflow ON stack.id = Overflow.id;
Best Practice Gebruik geen *
tenzij u fouten opspoort of de rij (en) ophaalt in associatieve arrays, anders kunnen schemawijzigingen (ADD / DROP / kolommen herschikken) leiden tot vervelende toepassingsfouten. Als u de lijst met kolommen in uw resultatenset opgeeft, kan de queryplanner van MySQL vaak de query optimaliseren.
Voors:
- Wanneer u kolommen toevoegt / verwijdert, hoeft u geen wijzigingen aan te brengen waar u
SELECT *
hebt gebruikt - Het is korter om te schrijven
- Je ziet ook de antwoorden, dus kan
SELECT *
-gebruik ooit gerechtvaardigd zijn?
nadelen:
- U retourneert meer gegevens dan u nodig hebt. Stel dat u een VARBINARY-kolom toevoegt die 200 k per rij bevat. U hebt deze gegevens slechts op één plaats nodig voor één record - met
SELECT *
krijgt u uiteindelijk 2 MB terug per 10 rijen die u niet nodig hebt - Expliciet over welke gegevens worden gebruikt
- Als u kolommen opgeeft, krijgt u een foutmelding wanneer een kolom wordt verwijderd
- De queryprocessor moet wat meer werk doen - uitzoeken welke kolommen er op de tafel staan (bedankt @vinodadhikary)
- U kunt gemakkelijker vinden waar een kolom wordt gebruikt
- Je krijgt alle kolommen in joins als je SELECT * gebruikt
- U kunt ordinale verwijzingen niet veilig gebruiken (hoewel het gebruik van ordinale verwijzingen voor kolommen op zichzelf een slechte gewoonte is)
- In complexe query's met
TEXT
velden kan de query worden vertraagd door minder optimale tijdelijke tabelverwerking
SELECTEER MET WAAR
vraag
SELECT * FROM stack WHERE username = "admin" AND password = "admin";
Resultaat
+------+----------+----------+
| id | username | password |
+------+----------+----------+
| 1 | admin | admin |
+------+----------+----------+
1 row in set (0.00 sec)
Zoekopdracht met een geneste SELECT in de WHERE-component
De WHERE
component kan elke geldige SELECT
instructie bevatten om complexere query's te schrijven. Dit is een 'geneste' zoekopdracht
vraag
Geneste query's worden meestal gebruikt om enkele atomaire waarden uit query's te retourneren voor vergelijkingen.
SELECT title FROM books WHERE author_id = (SELECT id FROM authors WHERE last_name = 'Bar' AND first_name = 'Foo');
Selecteert alle gebruikersnamen zonder e-mailadres
SELECT * FROM stack WHERE username IN (SELECT username FROM signups WHERE email IS NULL);
Disclaimer: Overweeg het gebruik van joins voor prestatieverbeteringen bij het vergelijken van een hele resultaatset.
SELECTEER met 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" overal:
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 |
+----+-----------+
Begint met "adm":
SELECT * FROM stack WHERE username LIKE "adm%";
+----+----------+
| id | username |
+----+----------+
| 1 | admin |
| 3 | adm |
| 6 | adm now |
+----+----------+
Eindigt met "adm":
SELECT * FROM stack WHERE username LIKE "%adm";
+----+----------+
| id | username |
+----+----------+
| 3 | adm |
+----+----------+
Net zoals het %
-teken in een LIKE
component overeenkomt met een willekeurig aantal tekens, komt het _
-teken overeen met slechts één teken. Bijvoorbeeld,
SELECT * FROM stack WHERE username LIKE "adm_n";
+----+----------+
| id | username |
+----+----------+
| 1 | admin |
+----+----------+
Prestatie-opmerkingen Als er een index op de username
, dan
-
LIKE 'adm'
voert hetzelfde uit als `= 'adm' -
LIKE 'adm%
is een "bereik", vergelijkbaar metBETWEEN..AND..
Het kan goed gebruik maken van een index op de kolom. -
LIKE '%adm'
(of een variant met een leidend jokerteken) kan geen enkele index gebruiken. Daarom zal het langzaam zijn. Op tafels met veel rijen is het waarschijnlijk zo traag dat het nutteloos is. -
RLIKE
(REGEXP
) is meestal langzamer danLIKE
, maar heeft meer mogelijkheden. - Hoewel MySQL
FULLTEXT
indexering op veel soorten tabellen en kolommen biedt, worden dieFULLTEXT
indexen niet gebruikt om zoekopdrachten metLIKE
.
SELECTEER met Alias (AS)
SQL-aliassen worden gebruikt om de naam van een tabel of kolom tijdelijk te wijzigen. Ze worden meestal gebruikt om de leesbaarheid te verbeteren.
vraag
SELECT username AS val FROM stack;
SELECT username val FROM stack;
(Opmerking: AS
is syntactisch optioneel.)
Resultaat
+-------+
| val |
+-------+
| admin |
| stack |
+-------+
2 rows in set (0.00 sec)
SELECTEER met een LIMIT-clausule
Query:
SELECT *
FROM Customers
ORDER BY CustomerID
LIMIT 3;
Resultaat:
Klanten ID | Klantnaam | Contactnaam | Adres | stad | Postcode | land |
---|---|---|---|---|---|---|
1 | Alfreds Futterkiste | Maria Anders | Obere Str. 57 | Berlijn | 12209 | Duitsland |
2 | Ana Trujillo Emparedados y helados | Ana Trujillo | Avda. de la Constitución 2222 | México DF | 05021 | Mexico |
3 | Antonio Moreno Taquería | Antonio Moreno | Mataderos 2312 | México DF | 05023 | Mexico |
Best Practice Gebruik altijd ORDER BY
wanneer u LIMIT
; anders zijn de rijen die u krijgt onvoorspelbaar.
Query:
SELECT *
FROM Customers
ORDER BY CustomerID
LIMIT 2,1;
Uitleg:
Wanneer een LIMIT
clausule twee getallen bevat, wordt deze geïnterpreteerd als LIMIT offset,count
. In dit voorbeeld slaat de query dus twee records over en retourneert een.
Resultaat:
Klanten ID | Klantnaam | Contactnaam | Adres | stad | Postcode | land |
---|---|---|---|---|---|---|
3 | Antonio Moreno Taquería | Antonio Moreno | Mataderos 2312 | México DF | 05023 | Mexico |
Notitie:
De waarden in LIMIT
clausules moeten constanten zijn; het zijn mogelijk geen kolomwaarden.
SELECTEER met DISTINCT
De clausule DISTINCT
na SELECT
elimineert dubbele rijen uit de resultatenset.
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
werkt in alle kolommen om de resultaten te leveren, niet in afzonderlijke kolommen. Dit laatste is vaak een misvatting van nieuwe SQL-ontwikkelaars. Kortom, het is de onderscheidbaarheid op rijniveau van de resultatenset, niet de onderscheidbaarheid op kolomniveau. Om dit te visualiseren, kijk naar "Audi A1" in de bovenstaande resultatenset.
Voor latere versies van MySQL heeft DISTINCT
gevolgen voor het gebruik ervan naast ORDER BY
. De instelling voor ONLY_FULL_GROUP_BY
komt in het spel zoals te zien op de volgende MySQL-handleiding met de titel MySQL Handling of GROUP BY .
SELECTEER met LIKE (_)
Een _
-teken in een LIKE
clausulepatroon komt overeen met een enkel teken.
vraag
SELECT username FROM users WHERE users LIKE 'admin_';
Resultaat
+----------+
| username |
+----------+
| admin1 |
| admin2 |
| admin- |
| adminA |
+----------+
SELECTEER met CASE of IF
vraag
SELECT st.name,
st.percentage,
CASE WHEN st.percentage >= 35 THEN 'Pass' ELSE 'Fail' END AS `Remark`
FROM student AS st ;
Resultaat
+--------------------------------+
| name | percentage | Remark |
+--------------------------------+
| Isha | 67 | Pass |
| Rucha | 28 | Fail |
| Het | 35 | Pass |
| Ansh | 92 | Pass |
+--------------------------------+
Of met ALS
SELECT st.name,
st.percentage,
IF(st.percentage >= 35, 'Pass', 'Fail') AS `Remark`
FROM student AS st ;
NB
IF(st.percentage >= 35, 'Pass', 'Fail')
Dit betekent: ALS st.percentage> = 35 WAAR is en dan
'Pass'
retourneer ELSE return'Fail'
SELECTEER MET TUSSEN
U kunt de BETWEEN-clausule gebruiken om een combinatie van voorwaarden voor "groter dan gelijk EN kleiner dan gelijk" te vervangen.
Gegevens
+----+-----------+
| id | username |
+----+-----------+
| 1 | admin |
| 2 | root |
| 3 | toor |
| 4 | mysql |
| 5 | thanks |
| 6 | java |
+----+-----------+
Vraag met operators
SELECT * FROM stack WHERE id >= 2 and id <= 5;
Soortgelijke zoekopdracht met TUSSEN
SELECT * FROM stack WHERE id BETWEEN 2 and 5;
Resultaat
+----+-----------+
| id | username |
+----+-----------+
| 2 | root |
| 3 | toor |
| 4 | mysql |
| 5 | thanks |
+----+-----------+
4 rows in set (0.00 sec)
Notitie
TUSSEN gebruikt
>=
en<=
, niet>
en<
.
NIET TUSSEN gebruiken
Als u het negatieve wilt gebruiken, kunt u NOT
. Bijvoorbeeld :
SELECT * FROM stack WHERE id NOT BETWEEN 2 and 5;
Resultaat
+----+-----------+
| id | username |
+----+-----------+
| 1 | admin |
| 6 | java |
+----+-----------+
2 rows in set (0.00 sec)
Notitie
NIET TUSSEN gebruikt
>
en<
en niet>=
en<=
Dat wil zeggen,WHERE id NOT BETWEEN 2 and 5
is hetzelfde alsWHERE (id < 2 OR id > 5)
.
Als u een index hebt op een kolom die u gebruikt in een BETWEEN
zoekopdracht, kan MySQL die index gebruiken voor een bereikscan.
SELECTEER met datumbereik
SELECT ... WHERE dt >= '2017-02-01'
AND dt < '2017-02-01' + INTERVAL 1 MONTH
Natuurlijk kan dit worden gedaan met BETWEEN
en opname van 23:59:59
. Maar het patroon heeft deze voordelen:
- U hoeft de einddatum niet vooraf te berekenen (dit is vaak een exacte lengte vanaf het begin)
- U neemt niet beide eindpunten op (zoals
BETWEEN
doet) en typ ook '23: 59: 59 'niet om dit te vermijden. - Het werkt voor
DATE
,TIMESTAMP
,DATETIME
en zelfs deDATETIME(6)
microsecondenDATETIME(6)
. - Het zorgt voor schrikkeldagen, einde van het jaar, etc.
- Het is indexvriendelijk (dus
BETWEEN
).