SQL : interrogation de données

I. Définition

Une requête d'interrogation est une combinaison d'opérations portant sur des tables (ou relations) et dont le résultat est lui même une table, dont l'existence est éphémère.

 

II. Interrogation d'une table simple

1) Projection
a) L'instruction SELECT

L'instruction SELECT permet de déterminer les données à projeter (afficher) à partir de tables précisées dans la clause FROM.

SELECT *
FROM table;

Le signe * désigne tous les champs de la table. Cette requête renvoie donc tous les champs de tous les enregistrements de la table table.

b) Limitation de la projection

Il est possible de limiter la projection à certains champs en précisant leur nom après l'instruction SELECT, et en les séparant par des virgules.

SELECT champ1, champ2, champ3
FROM table;

c) Suppression des doublons

Dans certains cas, l'instruction SELECT renvoie des enregistrements ayant la même valeur. La clause DISTINCT permet de ne projeter que les enregistrements différents :

SELECT DISTINCT champ
FROM nom_table

d) Alias pour les colonnes

Il est possible de nommer les colonnes de la table renvoyée en résultat (que ce soit un champ ou une opération SQL) avec l'opérateur AS :

SELECT expr AS 'Alias'
FROM table

2) Restriction de lignes
a) La clause WHERE

La clause WHERE, utilisée après FROM, permet de spécifier des critères de restriction. Elle est suivi d'une condition qui sera évaluée pour chaque ligne de la table, et seules les lignes pour lesquelles la condition est vérifiée seront projetées.

SELECT *
FROM table
WHERE condition;

b) Les conditions

Les conditions peuvent contenir n'importe quelle expression logique, renvoyant vrai (ou faux). Ces expressions sont constituées de noms de champ ou de valeurs (quelque soit le type), éventuellement d'opérateurs arithmétiques (+; -; /; *), comparés avec des opérateurs de comparaison (=, >, <, >=, <=, <>) ou des opérateurs SQL (BETWEEN, IN, LIKE, IS NULL).

SELECT *
FROM table
WHERE champ = valeur;

c) Les opérateurs SQL
  • expr1 BETWEEN expr2 AND expr2 : renvoie vrai si la valeur de expr1 est comprise entre celles de expr2 et expr3 (bornes incluses)
  • expr1 IN (expr2, expr3, expr4) : renvoie vrai si la valeur de expr1 est égale à l'une des expressions dans la parenthèse.
  • expr LIKE chaine : renvoie vrai si la valeur de expr est égale à la valeur de chaine, une chaine de caractère qui peut contenir des caractères jokers (_ pour un seul caractère, % pour plusieurs caractères).
  • expr IS NULL : renvoie vrai si l'expression est vide
SELECT *
FROM table
WHERE champ BETWEEN valeur1 AND valeur2;
SELECT *
FROM table
WHERE champ LIKE "_ab%";
SELECT *
FROM table
WHERE champ IN (valeur1, valeur2, valeur3);
SELECT *
FROM table
WHERE champ IS NULL;
 
d) Conditions composées

Il est possible d'affiner la recherche dans les enregistrements en utilisant des conditions composées, formées de plusieurs conditions simples, combinées par des opérateurs logiques : AND, OR, XOR ou NOT.

Des parenthèses peuvent être utilisées pour imposer une priorité entre les conditions (sachant que le AND est par défaut prioritaire par rapport au OR).

SELECT *
FROM table
WHERE champ1 <> valeur1
AND champ2 < valeur2;

3) Tri des résultats d'une requête

Par défaut, les résultats d'une requête SQL ne sont pas triés. Grâce à l'opérateur ORDER BY, placé après la clause WHERE, il est possible de spécifier jusqu'à 16 critères hiérarchiques de tri, séparés par des virgules

Un critère de tri est soit le nom d'un champ de la table ou son alias, soit l'ordre d'un champ ou d'un alias dans la clause SELECT. Et pour chaque critère, il est possible de préciser si le tri se fait par ordre ascendant (par défaut) ou descendant, en rajoutant ASC ou DESC derrière le critère.

SELECT *
FROM table
WHERE condition
ORDER BY champ1, champ2 DESC;

 

III. Les jointures

1) Présentation

Une jointure est une opération permettant de combiner des informations venant de plusieurs tables (256 au maximum).

Lors que l'on utilise plusieurs tables, il est parfois nécessaire de préfixer par le nom de la table les champs pour lesquels une ambiguïté existerait. Et pour éviter d'utiliser le nom complet de la table, il est possible de donner un alias aux tables.

2) Jointure interne

Une jointure interne renvoie les enregsitrements dont une correspondance a été trouvée dans les deux tables. Elle est créée avec l'instruction INNER JOIN pour sélectionner la table à joindre à la table indiquée dans l'instruction FROM et l'instruction ON pour définir les champs représentant l'information commune aux deux tables. Il est également possible de faire des jointures avec plusieurs tables.

SELECT *
FROM table1 T1
INNER JOIN table2 T2
ON T1.champ1 = T2.champ2;
SELECT *
FROM table1 T1
INNER JOIN table2 T2
ON T1.champ10 = T2.champ20
INNER JOINT table 3 T3
ON T1.champ11 = T3.champ30;
 
 
3) Jointure externe

Une jointure externe renvoie les enregistrements dont une correspondance a été trouvée dans les deux tables, comme une jointure externe, mais ajoute en plus les enregistrements d'une table qui n'ont pas de correspondance avec la deuxième table. Une jointure externe se fait avec les instructions LEFT JOIN ou RIGHT JOIN pour définir la deuxième puis avec l'instruction ON pour définir le lien entre les deux tables.

L'instruction LEFT JOIN renvoie tous les enregistrements pour lesquels il y a une correspondance entre les deux tables plus les enregistrements de la table définie dans l'instruction FROM qui n'ont pas de correspondance avec la table définie dans l'instruction LEFT JOIN. L'instruction RIGHT JOIN renvoie tous les enregistrements pour lesquels il y a une correspondance entre les deux tables plus les enregistrements de la table définie dans l'instruction RIGHT JOIN qui n'ont pas de correspondance avec la table définie dans l'instruction FROM.

SELECT *
FROM table1 T1
LEFT JOIN table2 T2
ON T1.champ1 = T2.champ2;
SELECT *
FROM table1 T1
RIGHT JOIN table2 T2
ON T1.champ1 = T2.champ2;
 
 
4) Jointure réflexive

Une jointure reflexive permet de rassembler des informations venant d'une ligne d'une table avec des informations venant d'une autre ligne de la même table.

SELECT T1.champ1
FROM table T1
INNER JOIN table T2
ON T1.champ1 = T2.champ2

 

IV. Les sous-requêtes

Une condition peut faire appel au résultat d'une autre requête. Une sous interrogation ramenant aucune ligne provoque un code erreur, une sous interrogation ramenant plusieurs lignes doit être utilisé avec l'opérateur IN, et une sous interrogation ramenant une ligne doit être utilisé avec l'opérateur =.

SELECT *
FROM table1
WHERE champ1 IN
 (SELECT champ2
  FROM table
  WHERE champ3 = valeur
 ); 
 SELECT *
FROM table1
WHERE champ1 =
 (SELECT champ2
  FROM table
  WHERE champ3 = valeur
 );

 

V. Les opérations

1) Présentation

Il existe des fonctions SQL permettant de réaliser des opérations sur une colonne, c'est-à-dire sur un champ de tous les enregistrements d'une table. On utilise généralement ces fonctions, dites d'agrégat, dans l'instruction SELECT, mais aussi dans les clauses WHERE, HAVING ou ORDER BY.

2) Les fonctions d'agrégat SQL
  • SUM(...) : somme des valeurs
  • AVG(...) : moyenne des valeurs
  • MIN(...) : minimum des valeurs
  • MAX(...) : maximum des valeurs
  • COUNT(...) : nombre de valeur
SELECT COUNT(champ)
FROM table;
SELECT MIN(champ)
  FROM table;
SELECT AVG(champ)
FROM table;
SELECT SUM(champ)
FROM table;

 

VI. Les regroupements de résultats

1) La clause GROUP BY
a) Présentation

Il est possible, grâce à la clause GROUP BY, d'effectuer des opérations par groupe de données. Au lieu d'effectuer les calculs pour chaque enregistrement, cette clause permet de créer des groupes (ou sous-ensembles) et renvoie un résultat d'opération par groupe.

Utiliser la clause GROUP BY a une contrainte : tous les champs se trouvant dans l'instruction SELECT doivent se trouver également dans la clause GROUP BY (sauf les champs résultat d'une fonction d'agrégat).

b) Exemples

Modèle relationnel :

Service (IdServ, NomServ, LieuServ)
- Clé primaire : IdServ

Employe (IdEmp, NomEmp, DateEmbaucheEmp, SalaireEmp, ServiceEmp)
- Clé primaire : IdEmp
- Clé étrangère : ServiceEmp en référence à IdServ de Service

Nombre de salariés par service :

SELECT NomServ, COUNT(IdEmp)
FROM Employe
INNER JOIN Service
ON IdServ = ServiceEmp
GROUP BY IdServ, NomServ;

Nombre de salariés par lieu :

SELECT LieuServ, COUNT(IdEmp)
FROM Employe
INNER JOIN Service
ON IdServ = ServiceEmp
GROUP BY LieuServ;

Liste des services par ordre décroissant des salaires moyens :

SELECT NomServ, AVG(SalaireEmp) AS SalaireMoyen
FROM Employe
INNER JOIN Service
ON IdServ = ServiceEmp
GROUP BY IdServ, NomServ
ORDER BY SalaireMoyen DESC;

2) La clause HAVING
a) Présentation

La clause HAVING permet une restriction d'affichage sur les résultats d'une opération sur des groupes. Elle ne doit pas être confondue avec la clause WHERE qui permet une restriction sur les enregistrements auxquels appliquer l'opération. HAVING intervient après l'opération, WHERE est prise en compte avant l'opération.

b) Exemples

Liste des services avec leur salaire moyen dont le salaire moyen dépasse 20000 € :

SELECT NomServ, AVG(SalaireEmp) AS SalaireMoyen
FROM Employe
INNER JOIN Service
ON IdServ = ServiceEmp
GROUP BY NumService, NomService
HAVING SalaireMoyen > 20000;

Liste des services avec le salaire moyen des employés gagnant plus de 20000 € :

SELECT NomServ, AVG(SalaireEmp) AS SalaireMoyen
FROM Employe
INNER JOIN Service
ON IdServ = ServiceEmp
WHERE SalaireMoyen > 20000
GROUP BY NumService, NomService;