| 14.1 Manipulation de données : SELECT , INSERT , UPDATE , DELETE
 14 Syntaxe des commandes SQL
 Manuel de Référence MySQL 4.1 : Version Française
 
 . Syntaxe de DELETE
 . Syntaxe de DO
 . Syntaxe de HANDLER
 . Syntaxe de INSERT
 . Syntaxe de LOAD DATA INFILE
 . Syntaxe de REPLACE
 ->Syntaxe de SELECT
 . Sous-sélections ( SubSELECT )
 . Syntaxe de TRUNCATE
 . Syntaxe de UPDATE
 
 
 | 
  14.1.7 Syntaxe de SELECT 
 SELECT
  est utilisé pour obtenir des enregistrements venant d'une 
ou plusieurs tables.
Le support des commandes  
UNION
  et des sous-requêtes est disponibles depuis 
MySQL 4.0 et 4.1, respectivement.
Voir  Syntaxe de 
UNION
  et  Syntaxe des sous-requêtes .| 
SELECT [STRAIGHT_JOIN][SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
 [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS] [HIGH_PRIORITY]
 [DISTINCT | DISTINCTROW | ALL]
 select_expression,...
 [INTO {OUTFILE | DUMPFILE} 'nom_fichier' export_options]
 [FROM table_references
 [WHERE where_definition]
 [GROUP BY {unsigned_integer | nom_de_colonne | formula} [ASC | DESC], ...
 [HAVING where_definition]
 [ORDER BY {unsigned_integer | nom_de_colonne | formula} [ASC | DESC] ,...]
 [LIMIT [offset,] lignes]
 [PROCEDURE procedure_name(argument_list)]
 [FOR UPDATE | LOCK IN SHARE MODE]]
 | 
 
Chaque  
select_expr
  indique une colonne à lire.
table_references
  indique la ou les tables à utiliser.
La syntaxe est décrite dans  Syntaxe de 
JOIN
 .
where_definition
  indique les conditions que les lignes
sélectionnées doivent satisfaire. 
SELECT
  peut aussi être utilisée pour lire des lignes calculées, sans
référence à une table.
Par exemple : Tous les mots-clés utilisés doivent être donnés exactement dans 
le même ordre que ci-dessus. Par exemple, une clause  
HAVING
  doit être placée 
après toute clause  
GROUP BY
  et avant toute clause  
ORDER BY
 .| 
mysql> SELECT 1 + 1;-> 2
 | 
 
Après le mot  
SELECT
 , vous pouvez ajouter certaines options qui affectent le comportement
de la commande.  
Une expression  
SELECT
  peut recevoir un alias 
en utilisant  
AS
 . L'alias est utilisé de la 
même façon que le nom du champ et peut être employé
avec des clauses  
ORDER BY
  ou  
HAVING
 .  Par exemple : 
Le mot clé  
AS
  est optionnel lors de la création d'un alias 
pour une expression  
SELECT
 . L'exemple précédent aurait 
pu être écrit comme ceci :| 
mysql> SELECT CONCAT(last_name,', ',first_name) AS full_nameFROM mytable ORDER BY full_name;
 | 
 Comme  
AS
  est optionnel, un problème subtil peut survenir si vous
oubliez une virgule entre deux expressions de  
SELECT
  : MySQL va
interpréter la seconde comme un alias de la première. Par exemple, 
dans la commande suivante,  
columnb
  est traité comme un nom d'alias :| 
mysql> SELECT CONCAT(last_name,', ',first_name) full_nameFROM mytable ORDER BY full_name;
 | 
 | 
mysql> SELECT columna columnb FROM mytable;
 | 
Il n'est pas possible d'utiliser un alias de champ dans une clause  
WHERE
 ,
car la valeur du champ peut ne pas être définie lorsque la clause
 
WHERE
  est exécutée.
 Problèmes avec les 
alias
 .        
La clause  
FROM table_references
  indique les tables à partir desquelles nous allons
obtenir les enregistrements. Si vous indiquez le nom de plusieurs tables, vous faites une jointure.
Pour davantage d'informations sur la syntaxe des jointures, consultez  Syntaxe de 
JOIN
 .
Pour chaque table spécifiée, vous pouvez éventuellement indiquer un alias. 
L'utilisation de  
USE INDEX
 ,  
IGNORE INDEX
 ,
 
FORCE INDEX
  pour donner des conseils d'optimisation à l'optimiseur
d'index.  Syntaxe de 
JOIN
 .| 
tbl_name [[AS] alias][[USE INDEX (key_list)]
 | [IGNORE INDEX (key_list)]
 | [FORCE INDEX (key_list)]]
 | 
 
En MySQL 4.0.14, vous pouvez utiliser  
SET MAX_SEEKS_FOR_KEY=value
  comme une
alternative pour forcer MySQL à choisir un scan d'index, plutôt qu'un scan de table.
Vous pouvez faire référence à une table avec  
nom_de_table
  (au sein de la
base de données courante), ou avec  
dbname.nom_de_table
  pour expliciter le nom de la
base de données.
Vous pouvez vous référer à un champ avec  
nom_de_colonne
 ,  
nom_de_table.nom_de_colonne
 , ou
 
db_name.nom_de_table.nom_de_colonne
 .  Vous n'êtes pas obligés d'indiquer de préfixe
 
nom_de_table
  ou  
db_name.nom_de_table
  pour une référence à un champ dans un
 
SELECT
 , à moins que la référence ne soit ambigue.  
Consultez  Noms de base de données, tables, index, colonnes et alias , pour des exemples d'ambiguîtés qui 
nécessitent des formes plus explicites de référence à
des champs.
Depuis la version 4.1.0, vous êtes autorisés à spécifier  
DUAL
  comme nom de
table, dans les situations ou aucune table n'est référencé. C'est une fonctionnalité
pure de compatibilité, car certains autres serveurs requièrent cette syntaxe. 
| 
mysql> SELECT 1 + 1 FROM DUAL;-> 2
 | 
  
Une référence à une table peut être aliasée en utilisant  
nom_de_table [AS] alias_name
  : 
| 
mysql> SELECT t1.name, t2.salary FROM employee AS t1, info AS t2->        WHERE t1.name = t2.name;
 mysql> SELECT t1.name, t2.salary FROM employee t1, info t2
 ->        WHERE t1.name = t2.name;
 | 
Dans la clause  
WHERE
 , vous pouvez utiliser toutes les fonctions que 
MySQL supporte, hormis les fonctions d'agrégation.
 Fonctions et opérateurs . 
Les colonnes sélectionnées dans le résultat peuvent 
être nommées dans les clauses  
ORDER BY
  et  
GROUP BY
  
en utilisant leur nom de colonne, les alias ou leur position de colonne. 
Les positions commencent à 1 : 
Pour trier dans l'ordre inverse, ajoutez le mot-clé  
DESC
  (descendant) au nom du champ dans
la clause  
ORDER BY
  qui vous permet de trier.
Par défaut, l'ordre ascendant est utilisé; ceci peut être indiqué de façon
explicite en utilisant le mot-clé  
ASC
 .L'utilisation des positions de colonnes est obsolète, car la syntaxe a été
supprimée du SQL standard.| 
mysql> SELECT college, region, seed FROM tournament->        ORDER BY region, seed;
 mysql> SELECT college, region AS r, seed AS s FROM tournament
 ->        ORDER BY r, s;
 mysql> SELECT college, region, seed FROM tournament
 ->        ORDER BY 2, 3;
 | 
 
Si vous utilisez  
GROUP BY
 , les lignes sont triées en fonction des colonnes
 
GROUP BY
  comme si on avait ajouté la clause  
ORDER BY
  pour ces colonnes.
MySQL a amélioré la clause  
GROUP BY
  depuis la version 3.23.34 pour que vous
puissiez aussi spécifier  
ASC
  et  
DESC
  après le nom de la colonne :  
| 
SELECT a, COUNT(b) FROM test_table GROUP BY a DESC
 | 
MySQL améliore l'utilisation de  
GROUP BY
  en vous autorisant à l'utiliser
avec des champs qui ne sont pas mentionnés dans la clause  
GROUP BY
 .
Si vous n'obtenez pas les résultats que vous attendiez, lisez la
description de  
GROUP BY
 .
 Fonctions à utiliser dans les définitions 
GROUP BY
 .
Depuis MySQL 4.1.1,  
GROUP BY
  dispose de l'option  
WITH ROLLUP
 .
 Options de 
GROUP BY
 .
La clause  
HAVING
  peut faire référence à n'importe quel champs ou alias
défini dans  
select_expr
 . C'est évalué en dernier lieu, juste avant
que les éléments ne soient envoyés au client, sans aucune optimisation.
N'utilisez pas  
HAVING
  pour des éléments qui devraient être dans
la clause  
WHERE
 . Par exemple, n'écrivez pas ceci : 
Ecrivez plutôt cela :| 
mysql> SELECT nom_de_colonne FROM nom_de_table HAVING nom_de_colonne > 0;
 | 
 Dans les versions 3.22.5 et supérieures de MySQL, vous pouvez aussi écrire des requêtes ainsi :| 
mysql> SELECT nom_de_colonne FROM nom_de_table WHERE nom_de_colonne > 0;
 | 
 Dans des versions plus anciennes de MySQL, vous pouvez écrire à la place :| 
mysql> SELECT user,MAX(salary) FROM users->        GROUP BY user HAVING MAX(salary)>10;
 | 
 | 
mysql> SELECT user,MAX(salary) AS sum FROM users->        group by user HAVING sum>10;
 | 
La clause  
HAVING
  peut utiliser des fonctions d'agrégation, alors 
que la clause  
WHERE
  ne le peut pas :  
Cependant, cela ne fonctionne pas dans les anciennes versions du serveur MySQL,
: avant la version 3.22.5. Au lieu de cela, ajoutez un alias de colonne dans la 
liste de colonnes, et faites référence à cet alias dans la colonne  
HAVING
  :| 
mysql> SELECT user, MAX(salary) FROM users->     GROUP BY user HAVING MAX(salary)>10;
 | 
 | 
mysql> SELECT user, MAX(salary) AS max_salary FROM users->     GROUP BY user HAVING max_salary>10;
 | 
La clause  
LIMIT
  peut être utilisée pour limiter le nombre d'enregistrements retournés 
par la commande  
SELECT
 .  
LIMIT
  accepte un ou deux arguments numériques. Ces arguments doivent 
être des entiers constants.Avec un argument, la valeur spécifie le nombre de lignes à retourner
depuis le début du jeu de résultat.
Si deux arguments sont donnés, le premier indique le décalage 
du premier enregistrement à retourner,
le second donne le nombre maximum d'enregistrement à retourner.
Le décalage du premier enregistrement est 0 (pas 1) :
 
Pour être compatible avec PostgreSQL, MySQL supporte aussi la syntaxe :
 
LIMIT row_count OFFSET offset
 .
 Pour obtenir tous les enregistrement d'un certain décalage jusqu'à la fin du résultat,
vous pouvez utiliser de grands entier en tant que second paramètre :| 
mysql> SELECT * FROM table LIMIT 5,10;  # Retourne les enregistrements 6 à 15
 | 
 Si un seul argument est donné, il indique le nombre maximum d'enregistrements à retourner :| 
mysql> SELECT * FROM table LIMIT 95,18446744073709551615; # Retourne les enregistrements de 96 jusqu'au dernier.
 | 
 Autrement dit,  
LIMIT n
  est équivalent à  
LIMIT 0,n
 .| 
mysql> SELECT * FROM table LIMIT 5;     # Retourne les 5 premiers enregistrements
 | 
La forme  
SELECT ... INTO OUTFILE 'nom_fichier'
  de  
SELECT
  écrit les
lignes sélectionnées dans un fichier. Le fichier est crée sur le serveur et ne
peut y être déjà présent (cela permet entre autre d'éviter la destruction des tables
et de fichiers tel que  
/etc/passwd
 ). Vous devez avoir le droit  
FILE
  sur le
serveur pour utiliser cette forme de  
SELECT
 . 
SELECT ... INTO OUTFILE
  à pour but principal de vous permettre de réaliser des
dumps rapides des tables sur la machine serveur. Si vous voulez créer le fichier sur
une autre machine, vous ne pouvez utiliser  
SELECT ... INTO OUTFILE
 .
Dans ce cas là, vous pouvez utiliser à la place un programme client comme  
mysqldump --tab
 
ou  
mysql -e "SELECT ..." > fichier
  pour générer le fichier.
 
SELECT ...  INTO OUTFILE
  est le complément de  
LOAD DATA INFILE
 ;
La syntaxe pour la partie  
export_options
  de la requête se compose des mêmes clauses
 
FIELDS
  et  
LINES
  que celles utilisées avec la commande  
LOAD DATA INFILE
 .
 Syntaxe de 
LOAD DATA INFILE
 .
Dans le fichier résultant, seul les caractères suivants sont protégés par le caractère
 
ESCAPED BY
  : 
Si le caractère  
FIELDS ESCAPED BY
  est vide, aucun caractère n'est protégé,
et  
NULL
  vaut  
NULL
 , et non  
\N
 . Il est probable
que ce ne soit pas une bonne idée de spécifier un caractère de protection vide,
en particulier sir les valeurs de vos champs peuvent être n'importe quoi. 
Le caractère  
ESCAPED BY
 
Les premier caractère de  
FIELDS TERMINATED BY
 
Les premier caractère de  
LINES TERMINATED BY
ASCII 0
  est convertit en  
ESCAPED BY
  suivi de 0
( 
ASCII 48
 ). 
La raison de ce qui précède est que vous devez  
impérativement
  protéger chaque
caractère  
FIELDS TERMINATED BY
 ,  
ESCAPED BY
 , ou  
LINES TERMINATED BY
  pour
assurer une relecture fiable du fichier. Le caractère  
ASCII 0
  est échappé pour assurer
la lisibilité sur certains clients.
Comme le fichier résultant ne se doit pas d'être syntaxiquement conforme à SQL, vous n'avez
besoin d'échapper rien d'autre. 
Voila un exemple de relecture de fichier au format utilisé par plusieurs anciens programmes.
 | 
SELECT a,b,a+b INTO OUTFILE '/tmp/result.text'FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
 LINES TERMINATED BY '\n'
 FROM test_table;
 | 
 
Si vous utilisez  
INTO DUMPFILE
  au lieu de  
INTO OUTFILE
 , MySQL n'écrira qu'une seule
ligne dans le fichier, sans aucun caractère de fin de ligne ou de colonne, ni d'échappement.
Cela est utile lorsque vous voulez enregistrer un  
BLOB
  dans un fichier.
Note :
  notez que les fichiers crées par  
INTO OUTFILE
  et  
INTO DUMPFILE
 
sera lisible par tout les utilisateurs ! La raison est que le serveur MySQL 
ne peut créer de fichier appartenant à autre que l'utilisateur qui l'a mis en route.
(vous devez éviter d'exécuter  
mysqld
  en tant que root), le fichier doit 
se composer de mot lisible pour que les données puissent être récupérées.
Une clause  
PROCEDURE
  indique une procédure qui doit traiter les
lignes du jeu de résultat. Pour un exemple, voyez  La procédure Analyse .
Si vous utilisez la clause  
FOR UPDATE
  avec un gestionnaire de tables qui gère les verrous de lignes ou 
de pages, les lignes seront verrouillées.
 
Les options  
DISTINCT
 ,  
DISTINCTROW
  et  
ALL
  indiquent
quels enregistrements avec doublons doivent être retournés. Par défaut, c'est ( 
ALL
 ),
retournant ainsi tous les enregistrements.  
DISTINCT
  et  
DISTINCTROW
 
sont synonymes et indique que les doublons doivent être éliminés du résultat.
HIGH_PRIORITY
 ,  
STRAIGHT_JOIN
 , et les options commençants par
 
SQL_
  sont des extensions MySQL au standard SQL. 
HIGH_PRIORITY
  donne à une commande  
SELECT
  une plus grande priorité
qu'une commande qui modifie une table. Vous devez l'utiliser seulement pour les requêtes
qui sont très rapides et qui doivent être effectuées en premier lieu.
Une requête  
SELECT HIGH_PRIORITY
  s'exécutera sur une table verrouillée
en lecture même si une commande de mise à jour attend que la table soit libérée. 
HIGH_PRIORITY
  ne peut être utilisée avec les commandes  
SELECT
  qui font
partie d'une  
UNION
 . 
STRAIGHT_JOIN
  force l'optimiseur à joindre les tables dans l'ordre
dans lequel elles sont listées dans la clause  
FROM
 . Vous pouvez utiliser cela
pour accélérer la requête, si les tables sont réordonnées sub-optimalement par
l'optimiseur. 
 Syntaxe de 
EXPLAIN
 (Obtenir des informations 
SELECT
) .
 
STRAIGHT_JOIN
  peut aussi être utilisée dans la liste  
table_references
 .
 Syntaxe de 
JOIN
 .
SQL_BIG_RESULT
  peut être utilisé avec  
GROUP BY
  ou  
DISTINCT
 
pour indiquer à l'optimiseur que le résultat comportera beaucoup d'enregistrements. Dans ce cas,
MySQL utilisera si besoin directement les bases temporaires stockées sur le disque.
MySQL préférera, dans ce cas, trier que d'obtenir une table temporaire avec une clé sur
les éléments du  
GROUP BY
 .
SQL_BUFFER_RESULT
  forcera le résultat à être stocké dans une table
temporaire. Ceci va aider MySQL à libérer plus tôt les verrous des tables et aidera aussi
dans les cas ou l'envoi du résultat au client prend un temps assez conséquent.
SQL_SMALL_RESULT
 , une option spécifique à MySQL, peut être utilisée
avec  
GROUP BY
  ou  
DISTINCT
  pour indiquer à l'optimiseur que le résultat
sera petit. Dans ce cas, MySQL utilise des tables temporaires rapides pour stocker la table résultante
plutôt que d'utiliser le tri. Dans MySQL 3.23, ceci n'est normalement pas nécessaire.
SQL_CALC_FOUND_ROWS
  (version 4.0.0 et supérieure) indique à MySQL de calculer
combien d'enregistrements seront dans le jeu de résultats, indépendamment de n'importe quelle
clause  
LIMIT
 .
Le nombre d'enregistrements peut alors être obtenu avec  
SELECT FOUND_ROWS()
 .
 Fonctions diverses .Avant MySQL 4.1.0, cette option ne fonctionne pas avec  
LIMIT 0
 , qui est
optimisée pour se terminer instantanément (le résultat ne contiendra pas
de lignes). 
 Comment MySQL optimise 
LIMIT
 .
SQL_CACHE
  demande à MySQL de ne pas stocker le résultat de la requête 
si vous utilisez  
query_cache_type
  avec la valeur  
2
  ou  
DEMAND
 .
Pour une requête qui utilise  
UNION
  ou une sous-requête, cette option prend
effet si elle est utilisée dans n'importe quelle partie de la requête  
SELECT
 .
 Le cache de requêtes MySQL .
SQL_CACHE
  indique à MySQL de stocker le résultat de la requête dans le cache de requêtes
si vous utilisez  
QUERY_CACHE_TYPE=2
  ( 
DEMAND
 ).
 Le cache de requêtes MySQL .
Pour les requêtes qui utilisent  
UNION
  ou les sous-requêtes, cette option
aura un effet sur toutes les parties de la requête  
SELECT
 . Sommaire : |