Tri de données avec le langage SQL

information-icon

Les premières épreuves du bac 2024 sont pour bientôt ! Consulte notre dossier sur le contrôle continu et le calcul des notes de ton bac pour maximiser ta préparation pour les révisions à ton examen 💪

Calculs et transformations dans une requête

  • À l'occasion d'une requête, il est possible de demander le résultat d'un calcul portant sur la valeur d'une colonne.
  • Il est stocké dans une colonne qui vient s'ajouter à la table résultat de la requête.
  • On peut effectuer des calculs impliquant une ou plusieurs colonnes en ayant recours aux opérateurs arithmétiques suivants : addition, soustraction, multiplication, division, reste dans la division.
  • La clause AS permet de baptiser le nom de la nouvelle colonne destinée à recueillir le résultat du calcul.
  • À l'occasion d'une requête, il est possible de demander le résultat d'un calcul portant sur l'ensemble des lignes d'une table.
  • Voici les fonctions statistiques simples que l'on peut appeler avec SQL :

COUNT(*) Nombre de lignes dans la table
MAX(colonnex) valeur maximum dans la colonne
MIN(colonnex) valeur minimum dans la colonne
AVG(colonnex) valeur moyenne de la colonne
SUM(colonnex) somme des valeurs de la colonne
  • D'autres transformations sur les colonnes sont possibles lors d'une requête d'interrogation, comme par exemple le passage en majuscule d'une colonne de type chaîne de caractères avec la fonction UPPER.
  • On peut également demander l'extraction du mois d'une date grâce à la fonction MONTH.

Agrégats et tri

  • On effectue une opération d'agrégation pour regrouper les lignes d'une table par la même valeur qu'elles contiennent dans une colonne.
  • L'objectif d'effectuer une agrégation est, en général, de pratiquer des calculs statistiques sur les groupes ainsi constitués.
  • La clause employée pour pratiquer une agrégation est GROUP BY :
    SELECT nomColonne1, fonction statistique
    FROM nomTable
    GROUP BY nomColonne1;
  • On peut ajouter une opération de filtrage à la table résultant d'une opération sur agrégat.
  • La clause HAVING permet d'exprimer le critère de filtrage sur cette table résultat.
  • Mais, lorsque l'on effectue une requête, la table résultat qui est restituée n'est pas triée par défaut.
  • Pour que ce soit le cas, on emploie le mot-clé ORDER BY suivi de la ou les colonnes sur lesquelles doit porter le tri.
  • Si plusieurs colonnes sont spécifiées dans la consigne de tri, alors le tri s'effectuera d'abord sur les valeurs de la colonne la plus à gauche, puis selon les valeurs des colonnes données pour le tri de gauche à droite.
  • Notons par ailleurs que le tri s'effectue par défaut de manière ascendant : l'option DESC inversera le tri pour le critère concerné.

Requêtes portant sur plusieurs tables

  • Pour retrouver des informations relatives à une même entité, on peut être amené à récupérer celles-ci dans plusieurs tables par le biais de ses associations.
  • Dans ce contexte où nous effectuons une requête portant sur plusieurs tables, une ambiguïté concernant la désignation de leurs colonnes respectives peut se présenter.
  • En effet, rien n'interdit de construire une base de données où un même nom de colonne peut figurer dans deux tables différentes.
  • Aussi, pour lever toute ambiguïté dans une requête qui porterait sur des tables ayant des colonnes nommées de la même manière, il est alors nécessaire de préfixer le nom de la colonne par celui de la table concernée.
  • Finalement, on préfèrera, qu'il y ait ambiguïté ou non, préfixer tous les noms de colonnes du nom de la table à laquelle celles-ci appartiennent.
  • Dans notre exemple, ou désignera nos champs idRecette ainsi :
  • recette.idRecette ;
  • etape.idRecette ;
  • Et voici une requête utilisant un préfixe de nom de table :
    SELECT recette.nomRecette, recette.categorie, recette.duree
    FROM recette;
  • À l'usage, on réalise que ce préfixe peut alourdir considérablement la rédaction de certaines requêtes, déjà complexes par ailleurs.
  • On peut alors faire le choix de substituer le préfixe du nom de la table par un alias, plus court, qui sera précisé dans la commande SQL avec le mot-clé AS.
  • Pour formuler des requêtes portant sur plusieurs tables, on utilise une opération de jointure.
  • Dans le cas de la base de données de notre club de cuisine, pour obtenir la liste des adhérent·e·s constituée de leur numéro d'adhérent, leur nom, leur prénom et de la ville où ils résident, nous pourrions formaliser la requête suivante :
    SELECT ad.idAdherent, ad.nomAdherent, ad.prenom, vi.nomVille
    FROM adherent AS ad, ville AS vi
    WHERE ad.idVille = vi.idVille
  • Cependant, il est nettement préférable d'avoir recours à un opérateur de jointure, nommé JOIN, spécifique aux requêtes portant sur plusieurs tables.
  • Le SGBD traitera alors la requête de manière optimisée.
  • La syntaxe requise pour effectuer une jointure est la suivante, dans le cadre de notre exemple :
    SELECT ad.idAdherent, ad.nomAdherent, ad.prenom, vi.nomVille
    FROM adherent AS ad JOIN ville AS vi ON ad.idVille = vi.idVille;
  • La jointure externe permet d’effectuer une jointure en incluant les lignes dont la clé étrangère qui fait le lien entre deux tables n’est pas renseignée.
  • Sachant que deux tables sont considérées dans cette jointure, il faut préciser laquelle des deux servira de référence.
  • Il faudra employer pour cela la clause OUTER JOIN.
  • Ainsi, toutes les lignes de la table qui servira de référence seront représentées dans la table résultat. L’attribut ou les attributs récupérés via la clé étrangère seront renseignés avec la valeur trouvée dans la seconde table, ou renseignée à « NULL » lorsque la clé étrangère n’est pas renseignée dans la première table.
  • Si par exemple on souhaite avoir la liste des adhérent·e·s constituée de leur numéro d’identification, leur nom, leur prénom, l’identifiant et le nom de chaque recette rédigée par un adhérent donné, on passera la commande suivante :
    SELECT a.idAdherent, a.nomAdherent, a.prenom, r.idRecette, r.nomRecette
    FROM adherent AS a JOIN recette AS r ON a.idAdherent = r.idAdherent
    ORDER BY a.idAdherent, r.nomRecette;
  • Mais nous souhaiterions que cette liste d’adhérent·e·s n’exclue pas ceux qui n’ont rédigé aucune recette. Pour cela, il faut faire appel à une jointure externe, en prenant adherent comme table de référence :
    SELECT a.idAdherent, a.nomAdherent, a.prenom, r.idRecette, r.nomRecette
    FROM adherent AS a LEFT OUTER JOIN recette AS r ON a.idAdherent = r.idAdherent
    ORDER BY a.idAdherent, r.nomRecette; LEFT indique que c’est la table qui apparaît à gauche dans la clause FROM qui sert de référence.
  • Pour terminer, on peut tenter de combiner différentes clauses. Si nous souhaitons par exemple connaître tous les adhérent·e·s qui n’ont pas proposé de recette, il suffira de passer la commande SQL suivante :
    SELECT a.idAdherent, a.nomAdherent, a.prenom, r.idRecette, r.nomRecette
    FROM recette AS r RIGHT OUTER JOIN adherent AS a ON a.idAdherent = r.idAdherent
    WHERE r.idRecette IS NULL;