Jusqu'à la version 4.1, seules les requêtes imbriquées de
la forme INSERT ... SELECT ...
et
REPLACE ... SELECT ...
étaient
supportées.
La clause IN()
peut être utilisée dans
certains contextes, pour tester la présence de valeur dans un
ensemble de données.
Il est souvent possible de réécrire une requête sans sous-requête :
SELECT * FROM t1 WHERE id IN (SELECT id FROM t2);
Cela peut se réécrire :
SELECT t1.* FROM t1,t2 WHERE t1.id=t2.id;
Les requêtes :
SELECT * FROM t1 WHERE id NOT IN (SELECT id FROM t2); SELECT * FROM t1 WHERE NOT EXISTS (SELECT id FROM t2 WHERE t1.id=t2.id);
peuvent être réécrites :
SELECT table1.* FROM table1 LEFT JOIN table2 ON table1.id=table2.id WHERE table2.id IS NULL;
Une clause LEFT [OUTER] JOIN
peut être
plus rapide qu'une sous-requête équivalent, car le serveur
va pouvoir l'optimiser bien mieux : c'est un fait qui n'est
pas spécifique à MySQL. Avant SQL-92, les jointures externes
n'existaient pas, et les sous-requêtes étaient la seule
méthode pour résoudre certains problèmes. Aujourd'hui, le
serveur MySQL et d'autres bases de données modernes offrent
toute une gamme de jointures externes.
Pour les sous-requêtes plus complexes, vous pouvez simplement
créer des tables temporaires pour contenir les résultats
intermédiaires. Dans certains cas, cela ne sera pas possible.
C'est notamment le cas des commandes de type
DELETE
, pour lesquelles le standard SQL ne
supporte pas les jointures, sauf pour les sous-requêtes. Dans
ces situations, trois solutions s'offrent à vous :
Passez en MySQL version 4.1.
Utilisez un langage de programmation procédural, comme
Perl
ou PHP
, pour
envoyer la requête SELECT
, lire les
clés primaires à effacer, et utiliser ces valeurs pour
soumettre des requêtes de type DELETE
(DELETE FROM ... WHERE ... IN (key1, key2,
...)
).
La troisième option est d'utiliser le client interactif
de mysql
pour construire et exécuter
une liste de commande DELETE
automatiquement, avec la fonction
CONCAT()
au lieu de l'opérateur
||
. Par exemple :
SELECT CONCAT('DELETE FROM tab1 WHERE pkid = ', "'", tab1.pkid, "'", ';') FROM tab1, tab2 WHERE tab1.col1 = tab2.col2;
Vous pouvez placer cette requête dans un fichier de
script, et rediriger son résultat vers le client en ligne
de commande mysql
, pour que ce dernier
lance une seconde instance de l'interprêteur :
shell> mysql --skip-column-names mydb < myscript.sql | mysql mydb
MySQL 4.0 supporte les commandes DELETE
multi-tables qui peuvent être utilisées pour effacer des
lignes dans une table en fonction d'informations qui sont dans
une autre table, ou même effacer des lignes simultanément
dans plusieurs tables. Les commandes UPDATE
multi-tables sont aussi supportés depuis la version 4.0.
This is a translation of the MySQL Reference Manual that can be found at dev.mysql.com. The original Reference Manual is in English, and this translation is not necessarily as up to date as the English version.