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:

  1. Lorsque vous ajoutez / supprimez des colonnes, vous n'avez pas à apporter de modifications lorsque vous avez utilisé SELECT *
  2. C'est plus court pour écrire
  3. Vous voyez aussi les réponses, alors SELECT * -usage peut-il être justifié?

Les inconvénients:

  1. 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
  2. Expliquer les données utilisées
  3. Spécifier des colonnes signifie que vous obtenez une erreur lorsqu'une colonne est supprimée
  4. Le processeur de requêtes doit faire plus de travail - déterminer quelles colonnes existent sur la table (merci @vinodadhikary)
  5. Vous pouvez trouver où une colonne est utilisée plus facilement
  6. Vous obtenez toutes les colonnes dans les jointures si vous utilisez SELECT *
  7. 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)
  8. 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 que LIKE , mais a plus de capacités.
  • Bien que MySQL offre l'indexation FULLTEXT sur de nombreux types de tables et de colonnes, ces index FULLTEXT ne sont pas utilisés pour répondre aux requêtes utilisant LIKE .

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 pour DATETIME(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 ).


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow