ActualitésEmploi

Apprendre SQL pour travailler avec les données : un parcours pratique et vérifiable

Retrouvez DigiTrendz dans vos sources préférées.

Suivre sur Google
Un adulte apprend les requêtes de base de données sur un ordinateur dans une bibliothèque.

Apprendre SQL ne consiste pas seulement à retenir SELECT et JOIN. Pour travailler avec des données, il faut comprendre ce que représente une ligne, vérifier les doublons et expliquer pourquoi un total est correct. Une requête qui s’exécute peut encore produire un résultat faux pour la question métier.

Ce parcours utilise un petit jeu fictif de clients et de commandes. Les exemples emploient un sous-ensemble SQL courant ; les fonctions et les types peuvent varier selon le moteur. Exécutez les exercices dans une base de démonstration, jamais directement dans une base de production pour découvrir les commandes.

En bref — Commencez par la granularité des données, puis sélection, filtres, agrégations et jointures. Vérifiez les résultats à la main sur un petit jeu connu. Gardez les opérations de modification pour un environnement de test, avec les droits appropriés.

Comprendre les tables avant la première requête

La table clients contient une ligne par client dans cet exercice. La table commandes contient une ligne par commande. Un même client peut avoir plusieurs commandes ; une commande possède un identifiant et une référence vers son client.

Cette description de la granularité est essentielle. Si une table contient plutôt une ligne par article de commande, additionner un montant de commande présent sur chaque ligne peut le compter plusieurs fois. Les noms de colonnes ne suffisent pas à définir le sens des données.

Voici le jeu fictif à utiliser. Les montants sont exprimés en euros entiers pour simplifier la lecture. Une base financière réelle doit employer des types et des conventions adaptés ; ne transposez pas automatiquement cet exercice à sa conception.

CREATE TABLE clients (
  id INTEGER PRIMARY KEY,
  nom TEXT NOT NULL
);
CREATE TABLE commandes (
  id INTEGER PRIMARY KEY,
  client_id INTEGER NOT NULL,
  montant INTEGER NOT NULL,
  statut TEXT NOT NULL,
  FOREIGN KEY (client_id) REFERENCES clients(id)
);
INSERT INTO clients VALUES
  (1, 'Aster'), (2, 'Boreal'), (3, 'Cobalt');
INSERT INTO commandes VALUES
  (101, 1, 100, 'payee'),
  (102, 1, 50, 'payee'),
  (103, 2, 80, 'annulee'),
  (104, 2, 120, 'payee');

Nous savons déjà plusieurs choses sans requête : il existe trois clients et quatre commandes. Trois commandes sont payées. Leur montant total est de 270 euros. Cobalt ne possède aucune commande dans ce jeu. Ces résultats attendus serviront de contrôle.

La documentation PostgreSQL présente les opérations de base, mais l’exercice est original et indépendant de ses exemples. Il permet de voir comment une question concrète se transforme en sélection, puis en résultat contrôlable.

Sélectionner ce qui répond à la question

Pour afficher les commandes payées, choisissez les colonnes utiles et filtrez le statut. Ajoutez un ordre explicite si vous souhaitez une présentation déterminée. Sans ORDER BY, il ne faut pas supposer que le moteur garantit l’ordre que vous observez une fois.

SELECT id, client_id, montant
FROM commandes
WHERE statut = 'payee'
ORDER BY id;

Le résultat attendu comprend 101, 102 et 104, avec leurs montants 100, 50 et 120. La commande annulée 103 est exclue. Vérifiez ces lignes avant de passer à un total : une agrégation correcte sur une sélection incorrecte reste incorrecte pour votre besoin.

Évitez SELECT * par réflexe dans une requête destinée à un traitement durable. Demander les colonnes nécessaires rend l’intention plus claire et limite la dépendance à des champs ajoutés ultérieurement. Pour explorer une table de test, l’usage peut être différent.

Le filtre doit correspondre à la définition métier. « Payée » n’est pas nécessairement « définitivement conservée » dans un autre système. Les remboursements et les changements d’état peuvent demander une autre logique. Le dossier sur les états et coûts du paiement montre pourquoi cette distinction compte.

Jointure gauche : résultat de l’exercice

RepèreCe qu’il indique
Aster2 commandes payées — 150 euros
Boreal1 commande payée — 120 euros
Cobalt0 commande payée — 0 euro
Population conservéeLes trois clients, même sans commande payée

Calculer un total et expliquer son périmètre

Une agrégation regroupe des lignes pour produire un résultat. Dans notre jeu, SUM calcule le montant des commandes payées sélectionnées. Le nombre de lignes et la somme répondent à des questions différentes, même s’ils peuvent être affichés ensemble.

SELECT COUNT(*) AS nombre_commandes,
       SUM(montant) AS montant_total
FROM commandes
WHERE statut = 'payee';

Nous attendons trois commandes et 270 euros. Expliquez ce résultat en une phrase : « total des montants des trois commandes dont le statut vaut payee dans ce jeu ». Cette précision évite de le présenter comme un chiffre d’affaires complet sans définir les autres règles.

Testez également les cas sans ligne. Les agrégats ne se comportent pas tous de la même manière lorsque l’ensemble est vide. Vérifiez la documentation du moteur et choisissez une présentation appropriée. Remplacer une valeur absente par zéro doit correspondre à un sens métier, pas uniquement à un souhait esthétique.

Les valeurs NULL demandent une attention particulière. Elles ne sont pas un zéro universel ni une chaîne vide. COUNT(*) compte les lignes ; COUNT(colonne) compte les valeurs non NULL de cette colonne. Cette différence devient importante après certaines jointures.

Grouper avant de comparer les clients

La question « combien chaque client a-t-il de commandes payées ? » demande de former des groupes. Dans un premier exercice, nous pouvons grouper directement les commandes payées par client_id.

SELECT client_id,
       COUNT(*) AS nombre,
       SUM(montant) AS total
FROM commandes
WHERE statut = 'payee'
GROUP BY client_id
ORDER BY client_id;

Aster, identifié par 1, possède deux commandes pour 150 euros. Boreal, identifié par 2, possède une commande payée pour 120 euros. Cobalt n’apparaît pas, car aucune ligne de commande payée ne porte son identifiant.

Cette absence n’est pas une erreur SQL. Elle répond au périmètre de départ : nous avons interrogé les commandes payées, pas tous les clients. Si la question exige de montrer aussi les clients sans commande, il faut changer l’organisation de la requête.

WHERE sélectionne les lignes avant l’agrégation. HAVING permet de filtrer les groupes après leur formation, selon les conditions prévues. Pour notre exercice, garder les clients dont le total payé dépasse 130 euros ferait apparaître seulement Aster.

SELECT client_id, SUM(montant) AS total
FROM commandes
WHERE statut = 'payee'
GROUP BY client_id
HAVING SUM(montant) > 130
ORDER BY client_id;

Comprendre le moment logique du filtre est plus utile que mémoriser la position d’un mot-clé. Vous pourrez alors expliquer pourquoi une condition portant sur une ligne et une condition portant sur un total ne sont pas interchangeables.

Une jointure doit conserver la bonne population

Une jointure interne associe les lignes satisfaisant la condition. Pour afficher le nom des clients ayant des commandes payées, reliez clients.id à commandes.client_id. La relation doit être définie, pas devinée à partir de champs aux noms similaires.

SELECT c.nom, o.id, o.montant
FROM clients AS c
JOIN commandes AS o ON o.client_id = c.id
WHERE o.statut = 'payee'
ORDER BY c.id, o.id;

Aster apparaît sur deux lignes et Boreal sur une. Cela correspond à une ligne par commande payée, pas une ligne par client. La répétition du nom est attendue. Avant d’additionner ou de compter, formulez cette nouvelle granularité.

Pour conserver tous les clients, une jointure externe gauche peut être adaptée. Placez ici la condition de statut dans la relation, afin de garder les clients sans commande payée dans ce scénario.

SELECT c.id, c.nom,
       COUNT(o.id) AS nombre_payees,
       COALESCE(SUM(o.montant), 0) AS total_paye
FROM clients AS c
LEFT JOIN commandes AS o
  ON o.client_id = c.id AND o.statut = 'payee'
GROUP BY c.id, c.nom
ORDER BY c.id;

Le résultat attendu est Aster : 2 et 150 ; Boreal : 1 et 120 ; Cobalt : 0 et 0. COUNT(o.id) évite de compter la ligne conservée pour Cobalt comme une commande. COALESCE représente ici l’absence de montant payé par zéro, selon le sens choisi pour l’exercice.

Le piège d’un filtre après une jointure externe

Si vous placez simplement la condition o.statut = ‘payee’ dans WHERE après une jointure gauche, les lignes sans commande correspondante ne satisferont pas cette condition. Cobalt peut alors disparaître. La requête s’exécute, mais ne répond plus à « tous les clients ».

Comparez les deux versions sur le petit jeu et décrivez la différence. Cet exercice est plus formateur qu’un long jeu de données où vous ne connaissez pas les résultats. Il montre comment la position d’un filtre peut changer la population.

Il ne s’agit pas d’une règle interdisant tous les filtres après une jointure externe. Une condition peut être appropriée selon la question. L’objectif est de comprendre son effet, puis de le vérifier sur un cas avec et sans correspondance.

Les systèmes intégrés par API peuvent produire des bases où certains objets manquent ou arrivent plus tard. Le guide sur les échanges entre logiciels rappelle pourquoi une absence doit être distinguée d’un échec ou d’un objet non encore transmis.

Les doublons peuvent être créés par la requête

Une relation un-à-plusieurs multiplie naturellement les lignes. Si vous joignez une commande à plusieurs articles et à plusieurs événements, le résultat peut multiplier les combinaisons. Un montant stocké au niveau commande risque alors d’être additionné plusieurs fois.

Avant une somme, contrôlez le nombre de lignes et les identifiants. Vérifiez si chaque objet apparaît autant de fois que prévu. DISTINCT peut masquer certains doublons, mais il ne corrige pas automatiquement une logique de jointure incorrecte.

Pour un besoin réel, il peut être nécessaire d’agréger chaque ensemble à la granularité voulue avant la jointure. La solution dépend du schéma et de la question. Une requête courte n’est pas meilleure si elle transforme involontairement les données.

Un test utile consiste à ajouter volontairement une seconde ligne liée à un objet dans votre base de démonstration. Si le total augmente alors que le montant métier n’a pas changé, vous avez repéré un effet de multiplication à examiner.

Modifier des données demande une autre discipline

Commencez les apprentissages avec un accès de lecture et des jeux fictifs. UPDATE, DELETE et les opérations de structure doivent être réservés à un environnement où leur effet est compris et autorisé. Une faute de filtre peut toucher plus de lignes que prévu.

Les transactions permettent de grouper des opérations selon les propriétés du moteur. La documentation PostgreSQL explique notamment BEGIN, COMMIT et ROLLBACK. Leur comportement doit être compris avec l’application et les contraintes de votre base.

Un exercice de modification doit définir l’état initial, l’effet attendu et le moyen de vérifier ou d’annuler. Ne supposez pas qu’une commande exécutée dans un outil sera toujours réversible après validation. Les possibilités dépendent du système et du moment.

Avant une intervention réelle, utilisez la procédure de l’organisation : sauvegarde, validation, environnement de test et personnes habilitées. Le fait de connaître une syntaxe ne constitue pas une autorisation de changer des données professionnelles.

Montrer une compétence avec un projet vérifiable

Pour un portfolio, présentez le schéma, la question, la requête et le résultat attendu sur des données fictives ou autorisées. Expliquez les limites et les cas particuliers testés. Un recruteur peut ainsi suivre votre raisonnement.

Le dossier sur un portfolio pour trouver un emploi aide à organiser cette présentation. En SQL, quelques requêtes bien expliquées peuvent être plus convaincantes qu’un tableau de bord dont personne ne comprend les calculs.

Ajoutez des tests : client sans commande, commande annulée, plusieurs commandes, valeur absente et relation multipliant les lignes. Ces cas montrent que vous ne vérifiez pas seulement le scénario favorable.

Indiquez le moteur utilisé et sa version lorsque cela compte. Une requête peut employer un dialecte ou une fonction spécifique. Ne présentez pas un essai dans un moteur comme une certification de fonctionnement dans tous les autres.

Une compétence SQL solide relie une question à une population, puis à un résultat contrôlé. Les mots-clés viennent ensuite. Savoir expliquer la granularité, les filtres et les effets des jointures permet de produire des données utiles, et de reconnaître les requêtes qui réussissent techniquement tout en répondant à la mauvaise question.

Passer du résultat juste à une exécution maîtrisée

Une requête correcte sur quatre lignes peut devenir coûteuse sur une base importante. Avant de l’optimiser, vérifiez qu’elle répond toujours à la bonne question. Accélérer un mauvais total ne corrige pas sa signification. Conservez donc les résultats attendus du petit jeu pendant les essais de performance.

Dans PostgreSQL, EXPLAIN montre le plan prévu par le moteur. EXPLAIN ANALYZE exécute l’opération pour fournir des observations supplémentaires : cette distinction doit être comprise avant son usage, particulièrement pour une requête qui modifie des données. Les coûts estimés ne doivent pas être lus comme des millisecondes universelles. Le plan dépend des données, des statistiques et de la configuration.

Pour débuter, cherchez les grandes étapes : lecture des tables, filtres, jointures, tri et agrégation. Demandez pourquoi autant de lignes sont examinées et combien sont finalement renvoyées. Un index peut être utile selon le besoin, mais en ajouter partout sans analyse augmente aussi les contraintes d’entretien et d’écriture. Faites valider les changements de structure dans un contexte professionnel.

LIMIT réduit le nombre de lignes retournées, mais ne prouve pas que le moteur évite tout travail important. Avec un tri ou une agrégation, une partie du traitement peut encore porter sur beaucoup de données. Si vous souhaitez une page reproductible, définissez un ordre adapté, avec un critère permettant de départager les égalités.

Enfin, gardez une fiche de requête : objectif, population, colonnes, granularité, résultat attendu, moteur et conditions d’exécution. Ajoutez une question que la requête ne permet pas de résoudre. Par exemple, notre total de commandes payées ne calcule ni la marge, ni les remboursements, ni une période qui n’existe pas dans le jeu. Cette limite explicite montre une compétence professionnelle : savoir ce que les données prouvent, et reconnaître ce qu’elles ne contiennent pas. Elle évite qu’un résultat correct soit réutilisé plus tard pour une décision à laquelle il n’a jamais été destiné.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *