La sélection en SQL
1 - Introduction
Nous
connaissons désormais l'allure des commandes SQL, dans le cadre de la sélection
simple. Il est temps que nous abordions :
- la sélection avec un ou plusieurs critères s'appliquant à un ou plusieurs champs ;
- la sélection multi-table, avec les jointures ;
- le regroupement ;
Chaque
fois que cela sera possible, nous ferons écrire le code SQL par le SGBD, en
partant de l'interface graphique de définition des requêtes avant de basculer
en mode SQL.
2 - La sélection en SQL
La
sélection permet d'extraire d'une table (ou de plusieurs tables liées par des
relations) les enregistrements répondant à un ou plusieurs critères.
Notons au passage qu'un critère peut aussi être appelé une condition.
Rappelons que l'ensemble des critères définit un filtre.
Notons au passage qu'un critère peut aussi être appelé une condition.
Rappelons que l'ensemble des critères définit un filtre.
A titre de premier exemple, cherchons dans la table "Personnes" (qui contient des noms, des prénoms, des adresses, etc.) les personnes dont le nom commence par la lettre "c" (majuscule ou minuscule, la casse n'importe pas).
Dans la grille de création de la requête, nous exprimons la condition sous la forme :
Comme "c*"
Si nous basculons en mode SQL, nous obtenons le code suivant
:
SELECT
Personnes.Nom, Personnes.Prénom
FROM
Personnes
WHERE
(((Personnes.Nom) Like "c*"));
Nous voyons que la condition s'exprime à l'aide de la clause
WHERE, suivie du nom du champ et de la condition. L'opérateur LIKE correspond
au français "Comme".
La clause WHERE est suivie d'un parenthèsage aussi
impressionnant qu'inutile. De plus, la qualification est superflue.
Si nous écrivons la requête sous la forme :
Si nous écrivons la requête sous la forme :
SELECT Nom,
Prénom
FROM Personnes
WHERE Nom
Like "c*";
elle fonctionne tout aussi bien, et le SGBD Access ne tente
de rétablir ni les parenthèses, ni la qualification.
Rajoutons un champ de type date dans la table
"Personnes", et sélectionnons les enregistrements relatifs à l'année
2002 seule.
Dans l'interface graphique, nous écrivons le critère sous la forme :
Dans l'interface graphique, nous écrivons le critère sous la forme :
>#31/12/2001# ET <#01/01/2003#
Si nous basculons en mode SQL, nous obtenons le code
suivant, après élimination des parenthèses et de la qualification :
SELECT Nom,
Prénom, Datea
FROM
Personnes
WHERE
Date>#12/31/2001# And Date<#1/1/2003#;
Nous pourrions faire des expériences analogues avec un champ
numérique (opérateurs arithmétiques), ou un champ booléen.
Les conditions sur le "Null" (champ non renseigné dans un enregistrement donné) s'écrivent à l'aide des expressions "Is Null" et "Is Not Null", dont la traduction française dans Access est "Est Null" ou "Est Pas Null".
On peut combiner plusieurs conditions à l'aide des opérateurs logiques "And", "Or" et "Not", dont la traduction française dans Access est "Et", "Ou" et "Pas".
Enfin, une condition peut comprendre des opérateurs arithmétiques ou des fonctions mathématiques (si elle porte sur des nombres) ou des opérateurs de chaînes (si elle porte sur du texte).
Les conditions sur le "Null" (champ non renseigné dans un enregistrement donné) s'écrivent à l'aide des expressions "Is Null" et "Is Not Null", dont la traduction française dans Access est "Est Null" ou "Est Pas Null".
On peut combiner plusieurs conditions à l'aide des opérateurs logiques "And", "Or" et "Not", dont la traduction française dans Access est "Et", "Ou" et "Pas".
Enfin, une condition peut comprendre des opérateurs arithmétiques ou des fonctions mathématiques (si elle porte sur des nombres) ou des opérateurs de chaînes (si elle porte sur du texte).
Remarque : notre façon de sélectionner l'année 2002 est d'un
usage très général, mais elle semble un peu lourde. L'utilisation de la
fonction "Year()" est plus élégante, mais cette fonction est
spécifique de VBA (Visual Basic for Applications, le langage de programmation
lié à Office).
Voici le code SQL correspondant :
Voici le code SQL correspondant :
SELECT Nom, Prénom, Date
FROM Personnes
WHERE Year([Date])=2002;
Nous constatons que la requête fonctionne toujours si nous
éliminons les crochets entourant l'argument "Date" dans la fonction
"Year".
Mais, dans l'interface graphique, la définition de la requête a changé ! Access a créé un nouveau champ intitulé "Année([Date])" et inscrit la valeur "2002"sur la ligne "Critères :". Notons au passage que l'on peut franciser "Year" en "Année" dans l'interface graphique d'Access, mais pas dans la programmation d'un module VBA ou l'écriture d'une commande SQL.
Mais, dans l'interface graphique, la définition de la requête a changé ! Access a créé un nouveau champ intitulé "Année([Date])" et inscrit la valeur "2002"sur la ligne "Critères :". Notons au passage que l'on peut franciser "Year" en "Année" dans l'interface graphique d'Access, mais pas dans la programmation d'un module VBA ou l'écriture d'une commande SQL.
3 - Les jointures
Effectuons
maintenant une requête sur deux tables ("Personne" et
"Communes") liées par une relation (appliquée aux champs
"code_commune").
La requête SQL s'écrit :
La requête SQL s'écrit :
SELECT Personnes.Nom, Personnes.Prénom, Personnes.Adresse,
Communes.commune, Communes.[code postal]
FROM Communes INNER JOIN Personnes ON Communes.code_commune
= Personnes.code_commune;
Cette fois, la qualification est obligatoire pour les champs
"code_commune", car il faut préciser de quelle table provient chaque
champ.
Mais la qualification est inutile pour les autres champs, car il ne peut y avoir d'ambiguïté.
Enfin, les crochets sont obligatoires pour évoquer le champ "code postal", dont le nom contient un espace (ils ne le sont pas pour "Prénom", parce que Access tolère les caractères accentués).
La requête SQL ainsi simplifiée s'écrit :
Mais la qualification est inutile pour les autres champs, car il ne peut y avoir d'ambiguïté.
Enfin, les crochets sont obligatoires pour évoquer le champ "code postal", dont le nom contient un espace (ils ne le sont pas pour "Prénom", parce que Access tolère les caractères accentués).
La requête SQL ainsi simplifiée s'écrit :
SELECT Nom, Prénom, Adresse, commune, [code postal]
FROM Communes INNER JOIN Personnes ON Communes.code_commune
= Personnes.Code_commune;
Nous voyons que "INNER JOIN" traduit l'existence
d'une relation entre les deux tables, et que "ON" précise quels sont
les champs mis en relation.
En SQL1, la commande précédente s'écrit différemment. La
clause INNER JOIN disparaît au profit d'une simple virgule, et la traduction de
la mise en relation des tables s'exprime à l'aide de la clause WHERE :
SELECT Nom, Prénom, Adresse, commune, [code postal]
FROM Communes, Personnes
WHERE Communes.code_commune = Personnes.code_commune;
Le SGBD Access accepte cette syntaxe mais, si nous revenons
dans l'interface graphique, nous constatons que cette dernière a changé : la
relation entre les deux tables a disparu ! Elle est remplacée par la condition
d'égalité de contenu entre les champs "code_commune" des deux tables
(condition exprimée en utilisant la syntaxe du SQL), comme le montre la figure
ci-dessous -- une façon élémentaire, mais parfaitement exacte, de créer une
relation entre deux tables. On notera que la relation normale entre les deux
tables n'est pas supprimée, mais simplement éliminée de la fenêtre de création
de la requête.
La clause INNER JOIN a fait son apparition avec la version 2
de SQL, parce que le besoin s'était fait sentir de préciser à quel type de
jointure appartenait une relation.
Plus précisément, on distingue :
Plus précisément, on distingue :
- la jointure interne, qui utilise INNER JOIN. Ne sont incluses dans le résultat final que les lignes qui se correspondent dans les deux tables. Ce cas est celui que nous avons traité précédemment ;
- la jointure externe gauche, dans laquelle INNER JOIN est remplacé par LEFT OUTER JOIN. Toutes les lignes de la première table sont incluses dans le résultat de la requête, même s'il n'existe pas de ligne correspondante dans la seconde table ;
- la jointure externe droite, dans laquelle INNER JOIN est remplacé par RIGHT OUTER JOIN. Toutes les lignes de la seconde table sont incluses dans le résultat de la requête, même s'il n'existe pas de ligne correspondante dans la première table.
Dans Access, la syntaxe des jointures gauche et droite est
simplifiée en LEFT JOIN et RIGHT JOIN, comme le montrent les deux exemples
suivants :
SELECT Nom, Prénom, Adresse, commune, [code postal]
FROM Personnes LEFT JOIN Communes ON Communes.code_commune =
Personnes.Code_commune;
SELECT Nom, Prénom, Adresse, commune, [code postal]
FROM Personnes RIGHT JOIN Communes ON Communes.code_commune
= Personnes.Code_commune;
La jointure peut également être précisée dans la fenêtre
graphique de définition d'une requête, comme nous l'avons vu au chapitre 13.
4 - Le regroupement
Nous
avons étudié le regroupement au chapitre 14. Nous réutilisons la même table,
intitulée "Résultats" et représentée ci-dessous.
Date Agence CA
06/01/2003 Nord 927,02 €
06/01/2003 Sud 1 098,46 €
06/01/2003 Est 561,29 €
07/01/2003 Nord 1 385,55 €
07/01/2003 Est 681,09 €
07/01/2003 Sud 1 401,56 €
Nous effectuons le regroupement par date et nous sommons sur
le CA. Nous obtenons le code SQL suivant :
SELECT Date, Sum(CA) AS CA_total
FROM
Résultats
GROUP BY
Date;
dans lequel le regroupement est exprimé par la clause GROUP
BY.
La requête fournit le résultat suivant :
La requête fournit le résultat suivant :
Date CA_total
06/01/2003 2
586,77 €
07/01/2003 3
468,20 €
Nous avons vu au chapitre 14 qu'une requête avec regroupement
peut être filtrée avant ou après regroupement.
Nous créons un exemple de filtrage avant regroupement en éliminant l'agence Est.
Nous obtenons le code SQL suivant :
Nous créons un exemple de filtrage avant regroupement en éliminant l'agence Est.
Nous obtenons le code SQL suivant :
SELECT Date, Sum(CA) AS CA_total
FROM
Résultats
WHERE
Agence Not Like "Est"
GROUP BY Date;
Nous reconnaissons une requête de sélection classique (dans
les trois premières lignes), suivie d'un regroupement. La requête fournit le
résultat suivant :
Date CA_total
06/01/2003 2
025,48 €
07/01/2003 2
787,11 €
Nous rajoutons ensuite un filtrage après regroupement en ne
retenant que les CA supérieurs à 2500 €. Nous obtenons le code SQL suivant :
SELECT Date, Sum(CA) AS CA_total
FROM
Résultats
WHERE
Agence Not Like "Est"
GROUP BY
Date
HAVING
Sum(CA)>2500;
dans lequel le filtrage après regroupement utilise la clause
HAVING.
La requête fournit le résultat suivant :
La requête fournit le résultat suivant :
Date CA_total
07/01/2003 2
787,11 €
D'une manière générale, une requête avec regroupement
s'écrit en SQL :
SELECT
.........
FROM
...........
WHERE ............
GROUP BY
...........
HAVING ............;
5 - Le comptage et les doublons
Nous
avons étudié les doublons au chapitre 15, en utilisant la table
"Résultats", dans laquelle nous avons effacé une des valeurs du champ
CA.
Date Agence CA
06/01/2003 Nord 927,02 €
06/01/2003 Sud 1 098,46 €
06/01/2003 Est 561,29 €
07/01/2003 Nord 1 385,55 €
07/01/2003 Est
07/01/2003 Sud 1 401,56 €
Nous créons une requête effectuant un regroupement sur le
champ "Date", et un comptage sur le champ "CA".
Le code SQL s'écrit :
Le code SQL s'écrit :
SELECT Date, Count(CA) AS Nombre_CA
FROM
Résultats
GROUP BY
Date;
Nous voyons que le comptage est effectué par la fonction
Count().
Le résultat de la requête est le suivant (la fonction de comptage ignore les Null) :
Le résultat de la requête est le suivant (la fonction de comptage ignore les Null) :
Date Nombre_CA
06/01/2003 3
07/01/2003 2
Si nous appliquons la fonction "Count" au champ de
regroupement lui-même, nous effectuons un comptage des doublons sur ce champ.
Le code SQL correspondant s'écrit :
Le code SQL correspondant s'écrit :
SELECT Date, Count(Date) AS Doublons_date
FROM Résultats
GROUP BY
Date;
La requête fournit le résultat suivant :
Date Doublons_Date
06/01/2003 3
07/01/2003 3
Si nous prenons le terme "doublon" au sens strict,
nous devons éliminer du résultat les comptages égaux à l'unité, en pratiquant
un filtrage après regroupement.
Le code SQL s'écrit alors :
Le code SQL s'écrit alors :
SELECT Date, Count(Date) AS Doublons_date
FROM
Résultats
GROUP BY
Date
HAVING
Count(Date)>1;
Le comptage des doublons sur deux champs s'écrit ainsi :
SELECT
Date, Agence, Count(*) AS Doublons
FROM
Résultats
GROUP BY
Date, Agence;
On notera que les deux champs doivent figurer dans la clause
de regroupement. On notera également que l'argument de la fonction Count()
devient l'astérisque, ce qui signifie que l'on compte les lignes sans se
référer à une colonne particulière.
Le code ci-dessus fournit le résultat suivant (il n'y a pas de doublons) :
Le code ci-dessus fournit le résultat suivant (il n'y a pas de doublons) :
Date Agence Doublons
06/01/2003 Nord 1
06/01/2003 Sud 1
06/01/2003 Est 1
07/01/2003 Nord 1
07/01/2003 Est 1
07/01/2003 Sud 1
Le regroupement sans comptage nous permet d'éliminer les
doublons. Si nous effectuons l'opération sur la colonne "Agence",
nous obtenons la liste des agences.
Le code SQL s'écrit :
Le code SQL s'écrit :
SELECT Agence
FROM Résultats
GROUP BY Agence;
La requête fournit le résultat suivant (les agences sont
triées par ordre alphabétique) :
Agence
Est
Nord
Sud
Terminons par le comptage sans regroupement, qui permet
d'obtenir le nombre d'enregistrements d'une table.
Le code SQL s'écrit :
Le code SQL s'écrit :
SELECT Count(*) AS Comptage
FROM Résultats;
La requête fournit le résultat suivant :
Comptage
6
5 - Conclusion
Comme
dans le chapitre précédent, le langage SQL ne nous a pas permis d'effectuer des
requêtes qui eussent été impossibles dans l'interface graphique d'Access. Il
nous a cependant permis de simplifier la recherche des doublons (Cf le chapitre
15).
Une commande SQL plus simple s'exécute plus vite, et la différence de temps devient sensible lorsqu'on traite un grand volume de données.
Une commande SQL plus simple s'exécute plus vite, et la différence de temps devient sensible lorsqu'on traite un grand volume de données.
The Casino at Quail Center | MapYRO
RépondreSupprimerThe Casino at 태백 출장샵 Quail 대전광역 출장샵 Center, Quail Center. Quail Center. 3131 Quail Center Boulevard. 의왕 출장안마 S. Chicago 서울특별 출장샵 IL 71946. 통영 출장마사지 United States.