Accueil du site > Les articles > Une requête SQL peut en cacher une autre
Version à imprimer Enregistrer au format PDF

Une requête SQL peut en cacher une autre

présentation des sous-requêtes utilisées dans les clauses FROM

lundi 6 septembre 2010, par Grégory Jarrige Visites  2114

Dans un précédent article, nous avons exploré les possibilités offertes par les sous-requêtes scalaires, dans ce nouvel article, nous allons étudier la possibilité d’utiliser des sous-requêtes à l’intérieur de clauses FROM.


La technique présentée dans ce chapitre fonctionne aussi bien avec MySQL qu’avec DB2. Elle ouvre un champ de possibilités impressionnant.

Démonstration avec un petit exemple.

J’ai une table des codes pays qui se présente comme ceci (c’est juste un extrait) :

select * from lstpays

CODFRA  CODISO  LIBELLE                
AFG      AF    AFGHANISTAN            
ZAF      ZA    AFRIQUE DU SUD        
ALA      AX    ALAND, ILES            
ALB      AL    ALBANIE                
DZA      DZ    ALGERIE                
DEU      DE    ALLEMAGNE              
AND      AD    ANDORRE                
AGO      AO    ANGOLA                
AIA      AI    ANGUILLA              
Etc…

Je voudrais connaître la liste des pays dont le code (zone CODFRA) commence par « A », le nombre de ceux donc le code commence par « B », etc…

Je peux bien sûr extraire la liste des premiers caractères avec la requête suivante :

select substr(codfra, 1, 1) as code from lstpays

CODE
A  
Z  
A  
A  
D  
D  
A  

Mais je ne peux pas faire de comptage dans la requête ci-dessus car pour faire un comptage sur chaque premier caractère (A, B, etc…) il me faut un GROUP BY sur cette valeur, or un GROUP BY ne peut se faire que sur une colonne existant déjà dans la table LSTPAYS. Pour m’en sortir, je pourrais créer une table SQL temporaire, puis travailler sur cette table, mais il y a plus astucieux. En effet, il me suffit d’encapsuler la requête précédente dans la clause FROM d’une autre requête, comme dans l’exemple suivant :

select code, count(*) as comptage from
(                      
select substr(codfra, 1, 1) as code from lstpays
) x                                                  
group by code                                      
order by code                                      

CODE       COMPTAGE
A               18
B               20
C               20
D                6
E                7
F                6
G               18
Etc…

Maintenant, je souhaite connaître, par ordre décroissant, la liste des caractères avec leurs scores respectifs. Je peux encapsuler la requête précédente dans la clause FROM d’une autre sous-requête, ce qui me donne ceci :

select * from
(                                  
select code, count(*) as comptage from
(          
select substr(codfra, 1, 1) as code from lstpays
) x                                                
group by code                                    
order by code                                    
) y                                              
order by comptage desc                            

CODE       COMPTAGE
M               24
S               22
C               20
B               20
A               18
G               18
T               15
P               14
N               12
Etc…

Et si je ne veux voir apparaître que ceux dont le score est supérieur ou égal à 20, je peux écrire ceci :

select * from
(                                  
select code, count(*) as comptage from
(          
select substr(codfra, 1, 1) as code from lstpays
) x                                                
group by code                                    
order by code                                    
) y
where y.comptage >= 20  
order by y.comptage desc  

CODE       COMPTAGE
M               24
S               22
C               20
B               20