Activité 15 Requêtes S.Q.L. Objectif Interroger une base de données avec des requêtes SQL. Fiche de savoir associée Ressource à utiliser Csi1Projets.pdf (Dossier 4) B.1.1.b. 1 En cliquant sur l'objet "Requêtes" sous ACCESS, vous accédez au menu suivant Travail à faire 1 Création des requêtes sous ACCESS L activité 14 nous a permis de découvrir et d étudier la base de donnés «GestProj» de la SSII InfoDev. Dans cette activité, vous allez être amené à créer des requêtes d interrogation dans le langage SQL sous le SGBDR ACCESS. Définition de requêtes en mode SQL sous ACCESS Afin de comprendre les manipulations à effectuer sous ACCESS, nous allons prendre comme exemple une requête à rédiger en langage SQL : Sélectionner l ensemble des informations dont dispose la société InfoDev sur les clients habitant Rochefort. Dans la syntaxe SQL la requête est de la forme suivante : SELECT * FROM CLIENT WHERE VilleClient = ROCHEFORT ; Pour accéder à l environnement SQL sous ACCESS, il vous faut faire les manipulations suivantes : Ouvrir la base gestproj.mdb (par un double-clic dans l explorateur), 75 Ce support de cours prend appui sur les contextes de système d information élaborés par le Réseau CERTA, centre de ressources en informatique et gestion des systèmes d information de l Éducation nationale http://www.reseaucerta.org/gsi
Sous la boîte de dialogue «GESTPROJ : Base de données», choisir la commande «Créer une requête en mode Création». Cliquer sur "Fermer" pour accéder au choix des modes de création. Après avoir fermé la fenêtre «Ajouter une table», il vous faut sélectionner dans la barre d outils le mode SQL : Cette commande vous permet de rentrer dans l environnement (éditeur de texte) des requêtes SQL d interrogation, de mise à jour et de suppression des données sous ACCESS. On tape dans cette fenêtre, la requête qui affichera les informations relatives aux clients de Rochefort : La barre d outils suivante vous permet de voir le résultat de l instruction SQL via l icône «Exécuter» : 76
Vous obtenez, après cette manipulation, la table résultat suivante : Les différentes étapes énoncées dans cette description, vous permettent d implémenter différents types de requêtes sous Microsoft ACCESS. En terminale GSI, nous n utiliserons plus le générateur automatique (mode création) de requêtes, mais uniquement le langage SQL. Modifiez cette requête de manière à afficher uniquement le nom du client, sa ville et le nom du contact. Quels sont les opérateurs relationnels utilisés dans cette requête? 2 Requêtes mono-table (une seule table concernée) Déterminons la requête qui permet d obtenir le nom, et l adresse complète (rue, code postal et ville) des clients habitant en Charente. Ce département possède le code 16. La restriction devra donc porter sur les codes postaux commençant par 16. Quel est le type de ce champ? Comment peut-on restreindre la recherche à une partie du champ? Pour un champ de type texte, l opérateur LIKE permet de réaliser ce type de comparaison. Voici la requête SQL qui répond au besoin exprimé : SELECT CLIENT.NomClient, CLIENT.CPClient, CLIENT.RueClient, CLIENT. VilleClient FROM CLIENT WHERE CLIENT.CPClient Like 16* ; Remarque : Il est préférable de préfixer le nom de champ par le nom de la table (TABLE.champ) dans les requêtes SQL, même si ce préfixage n est pas toujours indispensable nous vous conseillons de le faire systématiquement. L astérisque * est un joker qui signifie ici : quelle que soit la valeur après 16. À vous maintenant de rédiger les requêtes qui répondent aux besoins suivants : Description, origine et date de fin des projets terminés. Cette liste sera triée par ordre chronologique des dates de fin. Description, origine et état des projets commencés en avril 2006. Nom, prénom et ancienneté des employés habitant en Charente-Maritime (ce département a le numéro 17). Pour vous aider à écrire cette requête, vous pouvez utiliser la fonction Now() qui retourne la date système. Liste des projets issus de devis qui n ont pas abouti. Cette liste sera triée par le code du pôle et par la date de réponse. 77
3 Requêtes portant sur plusieurs tables Un stagiaire a écrit certaines requêtes à destination du technico-commercial. Une de ces requêtes pose problème. Il vous est demandé de la corriger. SELECT PROJET.NomProjet, CLIENT.NomClient, PROJET.OrigineProjet, PROJET.EtatProjet, PROJET.DateReponse FROM PROJET, CLIENT ORDER BY PROJET.NomProjet ; À quel besoin cette requête correspond-elle? Testez cette requête et comparez le résultat obtenu avec le contenu de la table PROJET. Que constatez-vous? Lorsqu une requête nécessite plusieurs tables, il faut indiquer au SGBDR les conditions de jointure entre ces tables. En terminale, la condition de jointure utilisée est l égalité entre les champs communs (clé primaire d un côté et clé étrangère de l autre). Elle est indiquée après la clause WHERE (comme la condition de restriction). Cela correspond, en fait, à la «référence clé étrangère» établie dans le modèle relationnel préalable à l implantation de la base. Quel est le champ commun aux tables Projet et Client? Modifiez la requête en indiquant la condition de jointure. N oubliez pas de préfixer le nom des champs par le nom de la table : par exemple le champ CodePole de la table Pole se note Pole.CodePole. À vous maintenant de rédiger les requêtes qui répondent aux besoins suivants : Liste des projets avec le nom de pôle. Liste des projets avec nom de pôle et nom client. Liste des projets, du pôle réseau, qui sont terminés et concernaient les clients de Charente-Maritime (Code 17). 4 Requêtes utilisant des fonctions d agrégat Les fonctions d agrégats permettent d effectuer des calculs (par exemple des opérations statistiques) sur toute la table ou sur différents groupes de la table. Observons l exemple suivant : SELECT COUNT(*) AS NbClients FROM CLIENT ; La fonction COUNT() compte ici le nombre de ligne de la table CLIENT. À quoi sert le mot-clé AS? Prenons un autre exemple de requête SQL : SELECT CLIENT.VilleClient, COUNT(*) FROM Client GROUP BY CLIENT.VilleClient ; Cette fois-ci, la fonction COUNT() permet de compter le nombre de «lignes» par ville. La clause GROUP BY crée un groupe pour chaque valeur de VilleClient et détermine le nombre d enregistrements correspondants. 78
À vous maintenant de rédiger les requêtes qui répondent aux besoins suivants : Nombre de salariés par pôle (le nom du pôle sera affiché). Nombre de projets terminés par pôle. La requête suivante ne fonctionne pas : SELECT POLE.CodePole, POLE.LibellePole, COUNT(*) AS NbProjets FROM POLE, PROJET WHERE POLE.CodePole = PROJET.CodePole GROUP BY POLE.CodePole ; Quel est le problème? Corrigez cette requête. Examinons une nouvelle requête : SELECT CLIENT.VilleClient, COUNT(*) AS NbClient FROM CLIENT GROUP BY CLIENT.VilleClient HAVING COUNT(*) > 2; À quel besoin cette requête correspond-elle? Pourquoi utiliser la clause HAVING et non la clause WHERE? Il existe d autres fonctions d agrégat. Les principales fonctions sont : AVG, MAX, MIN et SUM. Indiquez pour chacune des fonctions citées, son utilité. Écrivez la requête SQL qui nous permet d obtenir la «date de début de projet» la plus ancienne. Observez la requête suivante : SELECT INTERVENANT.NumEmploye, INTERVENANT.NomEmploye, INTER- VENANT.DateEmbauche FROM INTERVENANT WHERE INTERVENANT.DateEmbauche = (SELECT MAX(INTERVENANT.DateEmbauche) FROM INTERVENANT) ; Quel est le résultat recherché? Quelle est l information visée par la requête interne (encadrée en vert)? 2 Éléments de réponses au questionnement élève 1 Création des requêtes sous ACCESS : Modifiez cette requête de manière à afficher uniquement le nom du client, sa ville et le nom du contact. SELECT CLIENT.NomClient, CLIENT.VilleClient, CLIENT.NomContact FROM CLIENT WHERE VilleClient = ROCHEFORT ; 79
Remarques Quels sont les opérateurs relationnels utilisés dans cette requête? SELECT : Opérateur de projection WHERE : Opérateur de restriction 2 Requêtes mono-table Description, origine et date de fin des projets terminés. Cette liste sera triée par ordre chronologique des dates de fin. SELECT PROJET.DescriptionProjet, PROJET.OrigineProjet, PROJET. DateFinProjet FROM PROJET WHERE PROJET.EtatProjet = Terminé ORDER BY PROJET.DateFinProjet ASC ; Le mot-clé ASC est facultatif, par défaut le tri se fait sur l ordre croissant (ascendant). Description, origine et état des projets commencés en avril 2006. SELECT PROJET.DescriptionProjet, PROJET.OrigineProjet, PROJET.Etat- Projet FROM PROJET WHERE PROJET.DateDebutProjet >= #01/04/2006# AND PROJET.DateDebutProjet <= #30/04/2006# ; Dans Access, en mode SQL, les dates sont souvent au format anglosaxon. Il faut donc inverser les mois et les jours. Pour fonctionner la restriction devient : WHERE PROJET.DateDebutProjet >= #04/01/2006# AND PROJET.DateDebutProjet <= #04/30/2006# ; Il est également possible d utiliser le mot-clé BETWEEN dans la restriction : WHERE PROJET.DateDebutProjet BETWEEN #04/01/2006# AND #04/30/2006# ; Nom, prénom et ancienneté des employés habitant en Charente- Maritime (département 17). Pour vous aider à écrire cette requête, vous pouvez utiliser la fonction Now() qui retourne la date système. SELECT INTERVENANT.NomEmploye, INTERVENANT.PrenomEmploye, (NOW() - INTERVENANT.DateEmbauche)/365 AS Ancienneté FROM INTERVENANT WHERE INTERVENANT.CPEmploye Like 17* ; L expression NOW() - INTERVENANT.DateEmbauche calcule la différence entre la date d aujourd hui et la date d embauche des salariés. Le résultat est en nombre de jours. Il faut le diviser par 365 pour obtenir des années. Le mot-clé AS permet de donner un titre plus explicite au champ calculé. Il est possible d améliorer la présentation en arrondissant le résultat obtenu. L expression devient ROUND((NOW() - INTERVENANT.DateEmbauche)/365,0). La fonction ROUND arrondit un réel à l entier supérieur. 80
Liste des projets issus de devis qui n ont pas abouti. Cette liste sera triée par le code du pôle et par la date de réponse. SELECT PROJET.NomProjet, PROJET.OrigineProjet, PROJET.CodePole, PROJET.DateReponse FROM PROJET ORDER BY PROJET.CodePole, PROJET.DateReponse ; 3 Requêtes portant sur plusieurs tables À quel besoin cette requête correspond-elle? L objectif de cette requête est d obtenir la liste des projets avec le nom des clients. Testez cette requête et comparez le résultat obtenu avec le contenu de la table PROJET. Que constatez-vous? On obtient 1 536 enregistrements, alors qu il n y a que 24 projets au total! Cette erreur provient de l absence de la condition de jointure. A retenir : si vous utilisez 2 tables dans une requête vous aurez une jointure, 3 tables, 2 jointures, en conclusion n tables, n-1 jointures. Quel est le champ commun aux tables Projet et Client? Il s agit du numéro client. Il est clé étrangère dans la table Projet et clé primaire dans Client. Modifiez la requête en indiquant la condition de jointure. N oubliez pas de préfixer le nom des champs par le nom de la table : par exemple le champ CodePole de la table Pole se note Pole.CodePole. SELECT PROJET.NomProjet, CLIENT.NomClient, PROJET.OrigineProjet, PROJET.EtatProjet, PROJET.DateReponse FROM PROJET, CLIENT WHERE CLIENT.NumClient = PROJET.NumClient ORDER BY PROJET.NomProjet ; Liste des projets avec le nom de pôle. SELECT PROJET.NomProjet, POLE.LibellePole, PROJET.OrigineProjet, PROJET.EtatProjet, PROJET.DateReponse FROM PROJET, POLE WHERE POLE.CodePole = PROJET.CodePole ORDER BY PROJET.NomProjet ; Liste des projets avec nom de pôle et nom client. SELECT PROJET.NomProjet, CLIENT.NomClient, POLE.LibellePole, PROJET.OrigineProjet, PROJET.EtatProjet, PROJET.DateReponse FROM PROJET, CLIENT, POLE WHERE CLIENT.NumClient = PROJET.NumClient AND PROJET.CodePole = POLE.CodePole ORDER BY PROJET.NomProjet ; Nous avons besoin de deux conditions de jointure dans cette requête, car il y a trois tables concernées. 81
Liste des projets, du pôle réseau, qui sont terminés et concernaient les clients de Charente-Maritime (Code 17). SELECT PROJET.NomProjet, CLIENT.NomClient, PROJET.OrigineProjet, PROJET.EtatProjet, PROJET.DateReponse, CLIENT.CPClient FROM PROJET, CLIENT, POLE WHERE CLIENT.NumClient = PROJET.NumClient AND PROJET.CodePole = POLE.CodePole AND POLE.LibellePole = Réseau AND CLIENT.CPClient LIKE 17* ; 4 Requêtes utilisant des fonctions d agrégat Les fonctions d agrégats permettent d effectuer des calculs (par exemple des opérations statistiques) sur toute la table ou sur différents groupes de la table. Observons l exemple suivant : SELECT COUNT(*) AS NbClients FROM CLIENT ; La fonction COUNT() compte ici le nombre de ligne de la table CLIENT. À quoi sert le mot-clé AS? Il permet de donner un titre au champ calculé. On dit qu on crée un alias. Nombre de salariés par pôle (le nom du pôle sera affiché). SELECT POLE.LibellePole, COUNT(INTERVENANT.NumEmploye) AS NbEmploye FROM POLE, INTERVENANT WHERE POLE.CodePole = INTERVENANT.CodePole GROUP BY POLE.LibellePole ; Nombre de projets terminés par pôle. SELECT POLE.LibellePole, COUNT(*) AS NbProjet FROM POLE, PROJET WHERE POLE.CodePole = PROJET.CodePole AND PROJET.EtatProjet = Terminé GROUP BY POLE.LibellePole ; Quel est le problème? Le libellé du pôle doit être également regroupé. Tout champ apparaissant dans le SELECT, doit se trouver également dans le GROUP BY. Corrigez cette requête. SELECT POLE.CodePole, POLE.LibellePole, COUNT(*) AS NbProjets FROM POLE, PROJET WHERE POLE.CodePole = PROJET.CodePole GROUP BY POLE.CodePole, POLE.LibellePole ; À quel besoin cette requête correspond-elle? Cette requête permet de connaître les villes où résident plus de 2 clients. Pourquoi utiliser la clause HAVING et non la clause WHERE? La clause HAVING exprime une restriction comme le WHERE. Une restriction qui s applique aux regroupements. La clause WHERE ne peut pas s utiliser avec les fonctions d agrégats. 82
Il existe d autres fonctions d agrégat. Les principales fonctions sont : AVG, MAX, MIN et SUM. Indiquez pour chacune des fonctions citées, son utilité. AVG : calcule la moyenne des valeurs pour un champ. MAX : détermine la plus grande valeur pour un champ. MIN : détermine la plus petite valeur pour un champ. SUM : calcule la somme des valeurs pour un champ. Écrivez la requête SQL qui nous permet d obtenir la «date de début de projet» la plus ancienne. SELECT MIN(PROJET.DateDebutProjet) FROM PROJET ; La date la plus ancienne correspond à la date la plus «petite». Quel est le résultat recherché? Cette requête permet de connaître l employé le plus récemment embauché. Quelle est l information visée par la requête interne (encadrée en rouge)? La requête interne (requête imbriquée) retourne la date d embauche la plus récente. Remarque Nous vous recommandons de refaire une synthèse du SQL sur la base Infodev via le lien Certa : http://www.reseaucerta.org/docs/exonets/infodevreqinteroaccess.pdf 83