Bureau d'étude PEIP - IS
SQL
Le langage SQL (pour Structured Querry Language) est un langage permettant de décrire des requêtes sur une base de données.
Une base de données SQL est composée de tablen c'est à dire de schémas permettant de décrire la structure des données. Ces tables possèdent un nom, ainsi qu'un ensemble de champs.
Prenons l'exemple d'une base de données servant à gérer un lycée. On pourra définir une table "élèves" qui contiendra les informations sur les élèves :

Comme on peut le voir, cette table contient plusieurs champs : le nom, le prénom, la date de naissance... L'un de ces champs a une particularité, il s'agit de la clé primaire. Ce champs est définit pour identifier de manière unique chacun des individus de la table. D'autres champs peuvent être des clés étrangères, c'est à dire des références vers une clé primaire d'une autre table. Par exemple ici, le champs "refcalsse" est une référence vers la clé primaire de la table "Classe" pour indiquer dans quelle classe se trouve l'éléve.
De tels liens entre les champs "clé étrangère" d'une table et les champs "clé primaire" d'une autre table sont appelés des relations. On peut ainsi définir le schéma relationnel d'une base de données en représentant toutes les tables et les relations entre elles.

On peut voir que sur ces relations se trouvent des nombres. Il s'agit de la cardinalité, qui indique combien d'éléments d'une table sont en relation avec une autre.
Prenons l'exemple de la relation entre la table "Classe" et la table "Élèves". On voit que dans le sens élèves vers classe, la cardinalité est de 1 car un élève n'appartient qu'à une classe. En revanche, elle est de "n" dans l'autre sens car une classe peut contenir (théoriquement) autant d'élèves qu'on le souhaite.
La clause SELECT
La première chose à connaître pour créer des requêtes SQL est l'utilisation de la clause SELECT. Celle-ci permet de préciser quels champs vous souhaitez afficher et de quelle(s) table(s) ils viennent. Par exemple, pour afficher les champs "Nom" et "Prénom" de la table "Enseignant", on écrira le code suivant :
FROM Enseignant;
Si on souhaite n'afficher que les valeurs distinctes, on utilisera le mot clef "DISTINCT" :
FROM Elève;
On peut également créer des alias qui permettent de renomer des champs, ce qui peut être utilie lorsqu'on crée un champs calculé. Par exemple, si on souhaite déduire 23% de tous les salaires bruts :
FROM Enseignant;
L'expression de critère quand à elle se fait grâce à l'utilisation de la clause "WHERE". Par exemple si on veut sélectionner tous les enseignants dont la matière est la numéro 3 (chimie), on écrira :
FROM Enseignant
WHERE Enseignant.refmatiere=3;
On pourra de même utiliser toutes les conditions type lt;, >, <=, >=, <> (différent), OU, ET,...
Attention cependant, si on veut comparer des chaînes de caractères (c'est à dire du texte) on utilisera l'opérateur LIKE. Par exemple, pour avoir tous les enseignant dont le prénom contient un "a" :
FROM Enseignant
WHERE Enseignant.Prénom LIKE "*a*";
On peut également ordonner les résultats d'une requête en utilisant la clause "ORDER BY". Par exemple, pour donner la liste des enseignants par ordre alphabéthique de Prénom et par ordre inverse de nom :
FROM Enseignant
ORDER BY Enseignant.Prénom ASC Enseignant.Nom DESC;
Enfin, on peut également utiliser un alias pour une table pour éviter d'avoir à écrire entièrement son nom à chaque fois. Reprenons l'exemple de la requête précédente en appelant la table "Enseignant" avec l'alias "e" :
FROM Enseignant AS e
ORDER BY e.Prénom ASC e.Nom DESC;
Jointures
En base de données, on appelle jointure le fait d'inclure deux tables dans une requête et de les mettre en correspondance en fonction d'une clef. Cette clef est une clef primaire dans l'une des table et une clef étrangère dans l'autre. C'est ce qu'on fait par exemple si on inclut la table "Enseignant" et la table "Matière" en faisant le lien entre "Enseignant.refmatiere" et "Matière.nummatiere". En SQL, cela s'écrit de la façon suivante :
FROM Enseignant, Matière
WHERE Enseigant.refmatiere = Matière.nummatiere;
Prenons le temps d'analyser le code ci-dessus : la première ligne précise les champs que l'on souhaite afficher, la seconde précise les tables qu'il faut inclure dans la requête, et enfin la troisième ligne précise sur quels champs se fait la liaison. Notez que pour simplifier l'écriture, on prendra l'habitude d'utiliser une notation avec des alias de table :
FROM Enseignant AS e, Matière AS m
WHERE e.refmatiere = m.nummatiere;
Il est bien sûr possible de rajouter des critères ensuite en utilisant le "AND". Par exemple, si on veut faire la même requête mais en n'affichant que les enseigants qui ont un salaire supérieur à 2000€, on écrira le code suivante :
FROM Enseignant AS e, Matière AS m
WHERE e.refmatiere = m.nummatiere
AND e.Salaire > 2000;
Regroupements
Pour faire des regroupements en SQL, on utilise la clause "GROUP BY" (qui signifie litéralement "regrouper par"). On combine toujours avec la clause "GROUP BY" l'utilisation d'une fonction, comme par exemple "COUNT". Voici une petite liste des fonctions les plus utilisés en SQL :
- - COUNT(x) : compte du nombre de ligne du champs x
- - SUM(x) : donne l'addition de toutes les lignes du champs x
- - AVG(x): donne la moyenne des lignes du champs x
- - MIN(x) : donne le minimum des lignes du champs x
- - MAX(x) : donne le maximum des lignes du champs x
Par exemple, si on souhaite afficher le nombre d'enseignant par matière, on pourra effectuer la requête suivante :
FROM Enseignant AS e, Matière AS m
WHERE e.refmatiere = m.nummatiere
GROUP BY m.Intitulé;
Littéralement, cette requête "compte" le nombre de numens par intitulé de matière. On notera qu'il ne faut pas pour autant oublier de préciser sur quels champs se fait la jointure (clause WHERE) et que la claise GROUP BY vient toujours après la clause WHERE.
Si jamais le regroupement doit s'effectuer sur plusieurs champs, il est nécessaire de tous les préciser dans la clause "GROUP BY", séparés par des virgules. Par exemple, pour afficher le nombre de fois où chaque enseignant voit chaque classe, on écrira :
FROM Enseignant AS e, Cours AS co, Classe AS c
WHERE co.refens = e.numens
AND co.refclasse = c.numclasse
GROUP BY e.Nom, e.Prénom, c.niveau;
On notera également que la clause GROUP BY n'est pas nécessaire lorsque la requête porte sur un seul champs sur une seule table. Par exemple, pour afficher le salaire minimum des enseignants, on écrit simplement :
FROM Enseignant AS e;
Il est possible d'exprimer des critères sur les regroupements de façon tout à fait classique. D'abord, pour exprimer un critère sur les valeurs des champs en eux même, cela se fait de façon tout à fait classique en utilisant la clause "WHERE". Par exemple, pour reprendre la requête précédente mais en comptant cette fois ci le nombre d'enseignant ayant un salaire supérieur à 1900€ par matière, on utilise la requête suivante :
FROM Enseignant AS e, Matière AS m
WHERE e.refmatiere = m.nummatiere
AND e.Salaire > 1900
GROUP BY m.Intitulé;
La seule différence entre cette requête et celle d'avant est l'ajout d'un critère avec "AND".
On peut également exprimer un critère directement sur le résultat du regroupement, en utilisant la clause "HAVING". Par exemple, si on souhaite effectuer la même requête que précédemment mais en n'affichant que les matières qui ont plus de deux enseignants, on utilisera le code suivant :
FROM Enseignant AS e, Matière AS m
WHERE e.refmatiere = m.nummatiere
GROUP BY m.Intitulé
HAVING COUNT(e.numens) >= 2;
On note qu'ici le "COUNT(e.numens)" n'est plus dans les champs sélectionnés avec la clause SELECT mais exprime un critère de sélection dans la clause HAVING.
Pour le dire clairement, WHERE et HAVING permettent tous les deux d'appliquer des criètres. WHERE permets de les appliquer avant le regroupement, HAVING de les appliquer après.
Sous-Requêtes
Pour effectuer une requête en utilisant une sous requête, il suffit de considérer la sous requête exactement comme une table classique. Par exemple, pour afficher l'enseignant ayant le plus petit salaire, commençons par faire une requête donnant le salaire minimum :
FROM Enseignant AS e;
Supposons que cette requête est enregistrée comme "sous_requête1". La requête principale utilisant cette sous requête sera la suivante :
FROM Enseignant AS e, sous_requête1 AS sr1 WHERE e.Salaire = sr1.min_salaire;
On inclut tout simplement la sous-requête dans la clause FROM comme s'il s'agissait d'une table classique, et on utilise ensuite une clause WHERE pour faire la corresponsance entre le champs salaire de la table Enseignant et le minimum calculé précédemment.