14.1.8 Sous-sélections ( SubSELECT )
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
. Les sous-requêtes comme opérateur scalaire . Comparaisons avec les sous-requêtes . Sous-requêtes avec les clauses ANY , IN et SOME . Sous-requêtes avec ALL . Sous-requêtes corrélées . EXISTS et NOT EXISTS . Sous-requêtes de ligne . Sous-requêtes dans la clause FROM . Erreurs de sous-requêtes . Optimisation des sous-requêtes ->Se passer des sous-requêtes avec les premières versions de MySQL
|
14.1.8.11 Se passer des sous-requêtes avec les premières versions de MySQL
Jusqu'à la version 4.0 inclue, 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.
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.
|