MySQL
SÉLECTIONNER
Recherche…
Introduction
SELECT
permet de récupérer des lignes sélectionnées dans une ou plusieurs tables.
Syntaxe
SELECT DISTINCT [expressions] FROM TableName [WHERE conditions]; /// Simple Select
SELECT DISTINCT (a), b ... est identique à SELECT DISTINCT a, b ...
SELECT [TOUS | DISTINCT | DISTINCTROW] [HIGH_PRIORITY] [STRAIGHT_JOIN] [SQL_SMALL_RESULT | SQL_BIG_RESULT] [SQL_BUFFER_RESULT] [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS] expressions FROM tables [conditions WHERE] [expressions GROUP BY] [condition HAVING] [expression ORDER BY [ASC | DESC]] [LIMIT [offset_value] number_rows | LIMIT number_rows OFFSET offset_value] [PROCEDURE nom_procédure] [INTO [OUTFILE 'nom_fichier' options | DUMPFILE 'nom_fichier' | @ variable1, @ variable2, ... @variable_n] [POUR MISE À JOUR | VERROUILLAGE EN MODE SHARE]; /// Syntaxe complète de sélection
Remarques
Pour plus d'informations sur l' SELECT
de SELECT
, consultez MySQL Docs .
SELECT par nom de colonne
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');
Question
SELECT id FROM stack;
Résultat
+------+
| id |
+------+
| 1 |
| 2 |
+------+
SÉLECTIONNEZ toutes les colonnes (*)
Question
SELECT * FROM stack;
Résultat
+------+----------+----------+
| id | username | password |
+------+----------+----------+
| 1 | admin | admin |
| 2 | stack | stack |
+------+----------+----------+
2 rows in set (0.00 sec)
Vous pouvez sélectionner toutes les colonnes d'une table dans une jointure en procédant comme suit:
SELECT stack.* FROM stack JOIN Overflow ON stack.id = Overflow.id;
Meilleure pratique Ne pas utiliser *
moins de déboguer ou d'extraire la ou les lignes dans des tableaux associatifs, faute de quoi les modifications du schéma (colonnes ADD / DROP / réorganiser) peuvent entraîner des erreurs d'application malveillantes. De plus, si vous donnez la liste des colonnes dont vous avez besoin dans votre jeu de résultats, le planificateur de requêtes de MySQL peut souvent optimiser la requête.
Avantages:
- Lorsque vous ajoutez / supprimez des colonnes, vous n'avez pas à apporter de modifications lorsque vous avez utilisé
SELECT *
- C'est plus court pour écrire
- Vous voyez aussi les réponses, alors
SELECT *
-usage peut-il être justifié?
Les inconvénients:
- Vous retournez plus de données que nécessaire. Disons que vous ajoutez une colonne VARBINARY qui contient 200k par ligne. Vous n'avez besoin que de ces données à un seul endroit pour un seul enregistrement - en utilisant
SELECT *
vous pouvez finir par retourner 2 Mo par 10 lignes dont vous n'avez pas besoin - Expliquer les données utilisées
- Spécifier des colonnes signifie que vous obtenez une erreur lorsqu'une colonne est supprimée
- Le processeur de requêtes doit faire plus de travail - déterminer quelles colonnes existent sur la table (merci @vinodadhikary)
- Vous pouvez trouver où une colonne est utilisée plus facilement
- Vous obtenez toutes les colonnes dans les jointures si vous utilisez SELECT *
- Vous ne pouvez pas utiliser le référencement ordinal en toute sécurité (bien que l'utilisation de références ordinales pour les colonnes soit une mauvaise pratique en soi)
- Dans les requêtes complexes avec des champs
TEXT
, la requête peut être ralentie par un traitement de table temporaire moins optimal
SELECT avec WHERE
Question
SELECT * FROM stack WHERE username = "admin" AND password = "admin";
Résultat
+------+----------+----------+
| id | username | password |
+------+----------+----------+
| 1 | admin | admin |
+------+----------+----------+
1 row in set (0.00 sec)
Requête avec un SELECT imbriqué dans la clause WHERE
La clause WHERE
peut contenir toute instruction SELECT
valide pour écrire des requêtes plus complexes. Ceci est une requête 'imbriquée'
Question
Les requêtes imbriquées sont généralement utilisées pour renvoyer des valeurs atomiques uniques à partir de requêtes à des fins de comparaison.
SELECT title FROM books WHERE author_id = (SELECT id FROM authors WHERE last_name = 'Bar' AND first_name = 'Foo');
Sélectionne tous les noms d'utilisateur sans adresse e-mail
SELECT * FROM stack WHERE username IN (SELECT username FROM signups WHERE email IS NULL);
Clause de non-responsabilité: envisagez d'utiliser des jointures pour améliorer les performances lors de la comparaison d'un ensemble de résultats complet.
SELECT avec 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" n'importe où:
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 |
+----+-----------+
Commence par "adm":
SELECT * FROM stack WHERE username LIKE "adm%";
+----+----------+
| id | username |
+----+----------+
| 1 | admin |
| 3 | adm |
| 6 | adm now |
+----+----------+
Se termine par "adm":
SELECT * FROM stack WHERE username LIKE "%adm";
+----+----------+
| id | username |
+----+----------+
| 3 | adm |
+----+----------+
Tout comme le caractère %
d'une clause LIKE
correspond à un nombre quelconque de caractères, le caractère _
correspond qu'à un seul caractère. Par exemple,
SELECT * FROM stack WHERE username LIKE "adm_n";
+----+----------+
| id | username |
+----+----------+
| 1 | admin |
+----+----------+
Notes de performance S'il existe un index sur le username
d' username
, alors
-
LIKE 'adm'
effectue la même chose que `= 'adm' -
LIKE 'adm%
est une "range", similaire àBETWEEN..AND..
Elle peut faire bon usage d'un index sur la colonne. -
LIKE '%adm'
(ou toute variante avec un caractère générique en tête ) ne peut utiliser aucun index. Par conséquent, ce sera lent. Sur les tables comportant de nombreuses lignes, il est probable qu’elle soit si lente qu’elle est inutile. -
RLIKE
(REGEXP
) a tendance à être plus lent queLIKE
, mais a plus de capacités. - Bien que MySQL offre l'indexation
FULLTEXT
sur de nombreux types de tables et de colonnes, ces indexFULLTEXT
ne sont pas utilisés pour répondre aux requêtes utilisantLIKE
.
SELECT avec Alias (AS)
Les alias SQL sont utilisés pour renommer temporairement une table ou une colonne. Ils sont généralement utilisés pour améliorer la lisibilité.
Question
SELECT username AS val FROM stack;
SELECT username val FROM stack;
(Remarque: AS
est syntaxiquement facultatif.)
Résultat
+-------+
| val |
+-------+
| admin |
| stack |
+-------+
2 rows in set (0.00 sec)
SELECT avec une clause LIMIT
Question:
SELECT *
FROM Customers
ORDER BY CustomerID
LIMIT 3;
Résultat:
N ° de client | Nom du client | Nom du contact | Adresse | Ville | Code postal | Pays |
---|---|---|---|---|---|---|
1 | Alfreds Futterkiste | Maria Anders | Obere Str. 57 | Berlin | 12209 | Allemagne |
2 | Ana Trujillo Emparedados et helados | Ana Trujillo | Avda. de la Constitución 2222 | Mexique DF | 05021 | Mexique |
3 | Antonio Moreno Taquería | Antonio Moreno | Mataderos 2312 | Mexique DF | 05023 | Mexique |
Meilleure pratique Utilisez toujours ORDER BY
lorsque vous utilisez LIMIT
; sinon les lignes que vous obtiendrez seront imprévisibles.
Question:
SELECT *
FROM Customers
ORDER BY CustomerID
LIMIT 2,1;
Explication:
Lorsqu'une clause LIMIT
contient deux nombres, elle est interprétée comme un LIMIT offset,count
. Ainsi, dans cet exemple, la requête ignore deux enregistrements et en renvoie un.
Résultat:
N ° de client | Nom du client | Nom du contact | Adresse | Ville | Code postal | Pays |
---|---|---|---|---|---|---|
3 | Antonio Moreno Taquería | Antonio Moreno | Mataderos 2312 | Mexique DF | 05023 | Mexique |
Remarque:
Les valeurs des clauses LIMIT
doivent être des constantes; ils peuvent ne pas être des valeurs de colonne.
SELECT avec DISTINCT
La clause DISTINCT
après SELECT
élimine les lignes en double du jeu de résultats.
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
fonctionne sur toutes les colonnes pour fournir les résultats, pas les colonnes individuelles. Ce dernier est souvent une idée fausse des nouveaux développeurs SQL. En bref, c'est la distinction au niveau des lignes de l'ensemble de résultats qui compte, et non la distinction au niveau des colonnes. Pour visualiser cela, regardez "Audi A1" dans le jeu de résultats ci-dessus.
Pour les versions ultérieures de MySQL, DISTINCT
a des implications sur son utilisation aux côtés de ORDER BY
. Le paramètre pour ONLY_FULL_GROUP_BY
entre en jeu, comme le montre la page du manuel MySQL suivante, intitulée MySQL Handling of GROUP BY .
SELECT avec LIKE (_)
Un caractère _
dans un motif de clause LIKE
correspond à un seul caractère.
Question
SELECT username FROM users WHERE users LIKE 'admin_';
Résultat
+----------+
| username |
+----------+
| admin1 |
| admin2 |
| admin- |
| adminA |
+----------+
SELECT avec CASE ou IF
Question
SELECT st.name,
st.percentage,
CASE WHEN st.percentage >= 35 THEN 'Pass' ELSE 'Fail' END AS `Remark`
FROM student AS st ;
Résultat
+--------------------------------+
| name | percentage | Remark |
+--------------------------------+
| Isha | 67 | Pass |
| Rucha | 28 | Fail |
| Het | 35 | Pass |
| Ansh | 92 | Pass |
+--------------------------------+
Ou avec 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')
Cela signifie que: si st.percentage> = 35 est TRUE, alors retourne
'Pass'
ELSE return'Fail'
SELECT avec entre
Vous pouvez utiliser la clause BETWEEN pour remplacer une combinaison de conditions "supérieures à égales ET inférieures à égales".
Les données
+----+-----------+
| id | username |
+----+-----------+
| 1 | admin |
| 2 | root |
| 3 | toor |
| 4 | mysql |
| 5 | thanks |
| 6 | java |
+----+-----------+
Interroger avec des opérateurs
SELECT * FROM stack WHERE id >= 2 and id <= 5;
Requête similaire avec BETWEEN
SELECT * FROM stack WHERE id BETWEEN 2 and 5;
Résultat
+----+-----------+
| id | username |
+----+-----------+
| 2 | root |
| 3 | toor |
| 4 | mysql |
| 5 | thanks |
+----+-----------+
4 rows in set (0.00 sec)
Remarque
BETWEEN utilise
>=
et<=
, non>
et<
.
En utilisant pas entre
Si vous souhaitez utiliser le négatif, vous pouvez utiliser NOT
. Par exemple :
SELECT * FROM stack WHERE id NOT BETWEEN 2 and 5;
Résultat
+----+-----------+
| id | username |
+----+-----------+
| 1 | admin |
| 6 | java |
+----+-----------+
2 rows in set (0.00 sec)
Remarque
NOT BETWEEN utilise
>
et<
et non>=
et<=
C'est-à-dire, oùWHERE id NOT BETWEEN 2 and 5
est identique àWHERE (id < 2 OR id > 5)
.
Si vous avez un index sur une colonne que vous utilisez dans une recherche BETWEEN
, MySQL peut utiliser cet index pour une analyse de plage.
SELECT avec plage de dates
SELECT ... WHERE dt >= '2017-02-01'
AND dt < '2017-02-01' + INTERVAL 1 MONTH
Bien sûr, cela pourrait être fait avec BETWEEN
et l'inclusion de 23:59:59
. Mais, le modèle a ces avantages:
- Vous ne pré-calculez pas la date de fin (qui est souvent une longueur exacte depuis le début)
- Vous n'incluez pas les deux points de terminaison (comme le fait
BETWEEN
), ni tapez "23: 59: 59" pour l'éviter. - Il fonctionne pour
DATE
,TIMESTAMP
,DATETIME
et même pourDATETIME(6)
inclus dans la microseconde. - Il prend en charge les jours bissextiles, en fin d'année, etc.
- Il est facile à index (donc est
BETWEEN
).