Requête SQL : les exemples essentiels expliqués, de SELECT WHERE aux jointures et CTE – illustration SQL

Requête SQL : les exemples essentiels expliqués, de SELECT WHERE aux jointures et CTE

Thématique
Data & business intelligence
Mis à jour
Lecture
13 min
Formation
Débuter en SQL : Requêtes, analyses et gestion de données

L'essentiel en 30 secondes

  • Une requête SQL est une instruction envoyée à une base de données pour lire, ajouter, modifier ou supprimer des données ; la plus courante est SELECT.
  • Les clauses d'une requête SELECT s'écrivent dans un ordre fixe : SELECT, FROM, JOIN, WHERE, GROUP BY, HAVING, ORDER BY, puis LIMIT selon le système.
  • WHERE filtre les lignes avant le regroupement, alors que HAVING filtre les groupes après le calcul des agrégats.
  • Une jointure relie deux tables par une colonne commune : INNER JOIN garde les correspondances, LEFT JOIN conserve toutes les lignes de la table de gauche.
  • Les CTE (clause WITH) et les fonctions de fenêtre comme RANK permettent d'écrire des analyses avancées de façon lisible, sans multiplier les sous-requêtes.
Sommaire de l'article
  1. Qu’est-ce qu’une requête SQL ?
  2. La base d’exemple utilisée
  3. Les requêtes SQL essentielles, exemple par exemple
  4. Requêtes SQL avancées : sous-requêtes, UNION, CTE et RANK
  5. Bonnes pratiques pour écrire des requêtes lisibles
  6. Les erreurs fréquentes dans une requête SQL
  7. Les différences de syntaxe entre systèmes
  8. Comment progresser sur les requêtes SQL ?
  9. En résumé

Une requête SQL est une instruction écrite en langage SQL pour interroger ou modifier une base de données : afficher les clients d’une ville, calculer le chiffre d’affaires par mois, relier les commandes aux produits, classer les meilleurs vendeurs. Ce guide rassemble les requêtes les plus utiles, chacune accompagnée d’un exemple concret et d’une explication ligne à ligne.

Il s’adresse aux débutants qui veulent comprendre la logique de chaque clause, et aux utilisateurs occasionnels qui cherchent un modèle fiable à adapter. Tous les exemples portent sur la même petite base (clients, produits, commandes) et fonctionnent dans SQLite, avec les équivalents SQL Server signalés quand la syntaxe diffère.

Qu’est-ce qu’une requête SQL ?

Une requête SQL est une phrase structurée qui décrit le résultat attendu d’une base de données relationnelle. On indique quelles colonnes afficher, depuis quelles tables, avec quels filtres, regroupements et tris ; le système de gestion de base de données détermine lui-même comment l’exécuter. La requête de lecture s’écrit avec SELECT, les modifications avec INSERT, UPDATE et DELETE.

Les clauses d’une requête SELECT s’écrivent toujours dans le même ordre, mais la base les évalue dans un ordre logique différent. Comprendre cet écart évite beaucoup d’erreurs :

Ordre d’écritureClauseOrdre logique d’évaluation
1SELECT5
2FROM / JOIN1
3WHERE2
4GROUP BY3
5HAVING4
6ORDER BY6
7LIMIT7

C’est pourquoi un alias défini dans le SELECT ne peut généralement pas être utilisé dans le WHERE (évalué avant), mais peut l’être dans ORDER BY (évalué après).

La base d’exemple utilisée

Pour que les requêtes soient faciles à reproduire, voici les trois tables utilisées tout au long du guide :

  • clients : id_client, nom, ville, date_inscription ;
  • produits : id_produit, libelle, categorie, prix ;
  • commandes : id_commande, id_client, id_produit, date_commande, quantite.
CREATE TABLE clients (
  id_client INTEGER PRIMARY KEY,
  nom TEXT NOT NULL,
  ville TEXT,
  date_inscription TEXT
);

CREATE TABLE produits (
  id_produit INTEGER PRIMARY KEY,
  libelle TEXT NOT NULL,
  categorie TEXT,
  prix REAL
);

CREATE TABLE commandes (
  id_commande INTEGER PRIMARY KEY,
  id_client INTEGER REFERENCES clients(id_client),
  id_produit INTEGER REFERENCES produits(id_produit),
  date_commande TEXT,
  quantite INTEGER
);

Dans DB Browser for SQLite, créez une nouvelle base (Nouvelle base de données), puis exécutez ce script dans l’onglet Exécuter le SQL. Vous pouvez aussi importer vos propres tables depuis un CSV avec Fichier > Importer > Table depuis un fichier CSV. SQLite stocke ici les dates en texte au format AAAA-MM-JJ, ce qui permet de les comparer et de les trier correctement.

Les requêtes SQL essentielles, exemple par exemple

Exemple 1 — SELECT : choisir les colonnes

SELECT nom, ville
FROM clients;

SELECT liste les colonnes à afficher, FROM indique la table. SELECT * affiche toutes les colonnes : pratique pour explorer, à éviter dans une requête destinée à durer, car elle ramène des colonnes inutiles et dépend de la structure de la table.

Exemple 2 — AS : renommer une colonne et calculer

SELECT libelle        AS produit,
       prix           AS prix_ht,
       prix * 1.2     AS prix_ttc,
       ROUND(prix * 1.2, 2) AS prix_ttc_arrondi
FROM produits;

AS crée un alias, c’est-à-dire un nom d’affichage. Les opérations mathématiques (+, -, *, /) se font directement dans le SELECT. Attention, en SQLite comme en SQL Server, une division entre deux entiers renvoie un entier : 7 / 2 donne 3. Écrivez 7 / 2.0 ou convertissez une valeur pour obtenir 3,5.

Exemple 3 — SELECT WHERE : filtrer les lignes

SELECT nom, ville
FROM clients
WHERE ville = 'Lyon';

WHERE ne garde que les lignes qui respectent la condition. Les opérateurs de comparaison sont =, <> (différent), <, >, <= et >=. Le texte s’écrit entre apostrophes simples.

Exemple 4 — Combiner des conditions avec AND, OR, IN et BETWEEN

SELECT libelle, categorie, prix
FROM produits
WHERE categorie IN ('Bureau', 'Informatique')
  AND prix BETWEEN 50 AND 200
  AND (libelle LIKE '%pro%' OR prix < 60);
  • AND exige que toutes les conditions soient vraies, OR qu’au moins une le soit ;
  • IN remplace une série de OR sur la même colonne ;
  • BETWEEN inclut les deux bornes ;
  • LIKE recherche un motif : % remplace n’importe quelle suite de caractères, _ un seul caractère.

Mettez toujours des parenthèses quand vous mélangez AND et OR : AND est évalué en premier, ce qui produit des résultats inattendus.

Exemple 5 — ORDER BY et LIMIT : trier et limiter

SELECT libelle, prix
FROM produits
ORDER BY prix DESC, libelle ASC
LIMIT 5;

ORDER BY trie par une ou plusieurs colonnes, ASC (croissant, par défaut) ou DESC (décroissant). LIMIT garde les premières lignes. En SQL Server, on écrit SELECT TOP 5 libelle, prix FROM produits ORDER BY prix DESC.

Exemple 6 — DISTINCT : éliminer les doublons

SELECT DISTINCT ville
FROM clients
ORDER BY ville;

DISTINCT renvoie chaque combinaison de valeurs une seule fois : ici, la liste des villes où vous avez des clients.

Exemple 7 — Formater du texte

SELECT UPPER(nom)                         AS nom_majuscules,
       LOWER(ville)                       AS ville_minuscules,
       SUBSTR(nom, 1, 3)                  AS trois_lettres,
       LENGTH(nom)                        AS longueur,
       nom || ' (' || ville || ')'        AS libelle_complet,
       REPLACE(ville, 'Saint', 'St')      AS ville_abregee,
       TRIM(nom)                          AS nom_sans_espaces
FROM clients;

En SQLite, || concatène du texte. En SQL Server, on utilise + ou la fonction CONCAT(), et SUBSTRING() et LEN() à la place de SUBSTR() et LENGTH().

Exemple 8 — Jointure SQL : relier les commandes aux clients et aux produits

SELECT c.nom,
       p.libelle,
       o.date_commande,
       o.quantite,
       o.quantite * p.prix AS montant
FROM commandes AS o
INNER JOIN clients  AS c ON c.id_client  = o.id_client
INNER JOIN produits AS p ON p.id_produit = o.id_produit
WHERE o.date_commande >= '2026-01-01'
ORDER BY o.date_commande;

Chaque JOIN relie une nouvelle table grâce à la condition ON, qui associe la clé étrangère (o.id_client) à la clé primaire (c.id_client). Les alias courts (o, c, p) rendent la requête plus lisible et lèvent toute ambiguïté quand deux tables ont une colonne de même nom.

Exemple 9 — LEFT JOIN : trouver les clients sans commande

SELECT c.nom, c.ville
FROM clients AS c
LEFT JOIN commandes AS o ON o.id_client = c.id_client
WHERE o.id_commande IS NULL;

LEFT JOIN garde tous les clients, même sans commande ; pour ceux-là, les colonnes de la table commandes valent NULL. Le filtre IS NULL isole précisément ces clients. Ce motif sert à repérer toutes sortes d’orphelins : produits jamais vendus, factures sans paiement, salariés sans affectation.

Exemple 10 — GROUP BY : agréger les données

SELECT p.categorie,
       COUNT(*)                     AS nb_lignes,
       SUM(o.quantite)              AS quantite_totale,
       SUM(o.quantite * p.prix)     AS chiffre_affaires,
       ROUND(AVG(p.prix), 2)        AS prix_moyen
FROM commandes AS o
JOIN produits AS p ON p.id_produit = o.id_produit
GROUP BY p.categorie
ORDER BY chiffre_affaires DESC;

GROUP BY crée un groupe par valeur distincte de la colonne, et les fonctions d’agrégation (COUNT, SUM, AVG, MIN, MAX) calculent un résultat par groupe. Règle à retenir : toute colonne du SELECT qui n’est pas agrégée doit figurer dans le GROUP BY.

COUNT(*) compte les lignes, COUNT(colonne) compte les valeurs non nulles, et COUNT(DISTINCT colonne) les valeurs distinctes.

Exemple 11 — HAVING : filtrer sur un agrégat

SELECT c.nom,
       COUNT(*)                 AS nb_commandes,
       SUM(o.quantite * p.prix) AS total_achats
FROM commandes AS o
JOIN clients  AS c ON c.id_client  = o.id_client
JOIN produits AS p ON p.id_produit = o.id_produit
WHERE o.date_commande >= '2026-01-01'
GROUP BY c.nom
HAVING SUM(o.quantite * p.prix) > 1000
ORDER BY total_achats DESC;

WHERE retire d’abord les commandes antérieures à 2026, GROUP BY regroupe par client, puis HAVING ne garde que les clients qui dépassent 1 000 euros d’achats.

Exemple 12 — CASE WHEN : créer des catégories

SELECT libelle,
       prix,
       CASE
         WHEN prix < 50  THEN 'Entrée de gamme'
         WHEN prix < 200 THEN 'Milieu de gamme'
         ELSE 'Haut de gamme'
       END AS gamme
FROM produits;

CASE WHEN évalue les conditions dans l’ordre et renvoie la première qui est vraie ; ELSE couvre tous les autres cas. Combiné à GROUP BY ou à SUM, il permet aussi de compter conditionnellement :

SELECT ville,
       SUM(CASE WHEN date_inscription >= '2026-01-01' THEN 1 ELSE 0 END) AS nouveaux_clients,
       COUNT(*) AS total_clients
FROM clients
GROUP BY ville;

Requêtes SQL avancées : sous-requêtes, UNION, CTE et RANK

Exemple 13 — Sous-requête : comparer à une moyenne

SELECT libelle, prix
FROM produits
WHERE prix > (SELECT AVG(prix) FROM produits)
ORDER BY prix DESC;

La sous-requête entre parenthèses calcule d’abord le prix moyen, puis la requête principale garde les produits plus chers. Une sous-requête peut aussi servir dans un IN : WHERE id_client IN (SELECT id_client FROM commandes WHERE quantite > 10).

Exemple 14 — UNION : empiler des résultats

SELECT nom AS libelle, 'Client' AS type FROM clients
UNION ALL
SELECT libelle, 'Produit' AS type FROM produits
ORDER BY type, libelle;

UNION empile les résultats de plusieurs requêtes ayant le même nombre de colonnes, de types compatibles. UNION supprime les doublons, UNION ALL les conserve et s’exécute plus vite : utilisez UNION ALL quand les doublons sont impossibles ou souhaités.

Exemple 15 — IFNULL et COALESCE : gérer les valeurs nulles

SELECT nom,
       IFNULL(ville, 'Ville inconnue')             AS ville_sqlite,
       COALESCE(ville, 'Ville inconnue')           AS ville_standard
FROM clients;

NULL signifie « valeur absente ». On ne le teste jamais avec =, mais avec IS NULL ou IS NOT NULL. IFNULL existe en SQLite et MySQL, ISNULL en SQL Server, et COALESCE, qui accepte plusieurs arguments, fonctionne partout.

Exemple 16 — WITH (CTE) : découper une requête complexe

WITH ventes_client AS (
  SELECT o.id_client,
         SUM(o.quantite * p.prix) AS total
  FROM commandes AS o
  JOIN produits AS p ON p.id_produit = o.id_produit
  GROUP BY o.id_client
),
moyenne AS (
  SELECT AVG(total) AS total_moyen FROM ventes_client
)
SELECT c.nom, v.total
FROM ventes_client AS v
JOIN clients AS c ON c.id_client = v.id_client
CROSS JOIN moyenne AS m
WHERE v.total > m.total_moyen
ORDER BY v.total DESC;

Une CTE (Common Table Expression) nomme un résultat intermédiaire que l’on réutilise ensuite comme une table. La requête se lit de haut en bas, étape par étape, au lieu d’imbriquer des sous-requêtes sur plusieurs niveaux.

Exemple 17 — RANK : classer dans chaque groupe

WITH ca_produit AS (
  SELECT p.categorie,
         p.libelle,
         SUM(o.quantite * p.prix) AS ca
  FROM commandes AS o
  JOIN produits AS p ON p.id_produit = o.id_produit
  GROUP BY p.categorie, p.libelle
)
SELECT categorie,
       libelle,
       ca,
       RANK() OVER (PARTITION BY categorie ORDER BY ca DESC) AS rang
FROM ca_produit
ORDER BY categorie, rang;

RANK est une fonction de fenêtre : elle calcule un classement sans regrouper les lignes. PARTITION BY recommence le classement dans chaque catégorie, ORDER BY définit le critère. En cas d’égalité, RANK attribue le même rang et saute les suivants (1, 1, 3) ; DENSE_RANK ne saute pas (1, 1, 2) ; ROW_NUMBER numérote sans égalité. Pour garder le top 3 de chaque catégorie, ajoutez une CTE supplémentaire puis WHERE rang <= 3.

Exemple 18 — INSERT, UPDATE, DELETE dans une transaction

BEGIN TRANSACTION;

INSERT INTO clients (nom, ville, date_inscription)
VALUES ('Studio Est', 'Strasbourg', '2026-09-01');

UPDATE produits
SET prix = ROUND(prix * 1.05, 2)
WHERE categorie = 'Bureau';

DELETE FROM commandes
WHERE quantite = 0;

-- Vérifiez les résultats avec des SELECT, puis :
COMMIT;      -- pour valider
-- ROLLBACK; -- pour tout annuler

La transaction regroupe plusieurs modifications : soit elles sont toutes validées par COMMIT, soit toutes annulées par ROLLBACK. Avant chaque UPDATE ou DELETE, exécutez un SELECT avec la même clause WHERE pour vérifier les lignes visées.

Bonnes pratiques pour écrire des requêtes lisibles

Une requête SQL se relit bien plus souvent qu’elle ne s’écrit. Quelques conventions simples la rendent compréhensible par un collègue, ou par vous-même quelques mois plus tard :

  • Une clause par ligne : SELECT, FROM, chaque JOIN, WHERE, GROUP BY et ORDER BY commencent une nouvelle ligne.
  • Des mots-clés en majuscules et des noms de tables et de colonnes en minuscules : la structure saute aux yeux.
  • Des alias explicites (o pour commandes, c pour clients) et des alias de colonnes parlants (chiffre_affaires plutôt que total2).
  • Des colonnes nommées plutôt que SELECT *, pour savoir exactement ce que renvoie la requête.
  • Des commentaires avec -- pour expliquer une règle métier : « on exclut les commandes de test ».
  • Des CTE pour chaque étape logique, au lieu de sous-requêtes imbriquées sur trois niveaux.
  • Une requête testée par morceaux : exécutez d’abord la première CTE seule, vérifiez le nombre de lignes, puis ajoutez la suivante.

Enfin, quand une requête sert régulièrement à alimenter un rapport, enregistrez-la sous forme de vue dans la base : les outils de visualisation comme Looker Studio ou Power BI se connectent alors à un résultat stable et documenté.

Les erreurs fréquentes dans une requête SQL

ErreurSymptômeCorrection
WHERE ville = NULLAucune ligne renvoyéeWHERE ville IS NULL
Colonne non agrégée absente du GROUP BYErreur (SQL Server) ou valeur arbitraire (SQLite)Ajouter la colonne au GROUP BY ou l’agréger
WHERE SUM(montant) > 100Erreur d’agrégat mal placéDéplacer la condition dans HAVING
AND et OR mélangés sans parenthèsesRésultats trop nombreuxParenthéser les conditions OR
Jointure sans condition ON correcteLignes multipliées, totaux fauxVérifier la paire clé étrangère / clé primaire
LEFT JOIN suivi d’un filtre sur la table de droite dans WHERELe LEFT JOIN se comporte comme un INNER JOINDéplacer ce filtre dans la clause ON
Guillemets doubles autour d’un texteInterprété comme un nom de colonne selon le systèmeApostrophes simples pour les valeurs texte
Division entière7 / 2 = 3Écrire 7 / 2.0 ou convertir en décimal

Les différences de syntaxe entre systèmes

BesoinSQLiteSQL ServerMySQLPostgreSQL
Limiter les lignesLIMIT 10TOP 10 ou OFFSET … FETCHLIMIT 10LIMIT 10
Valeur de remplacement d’un NULLIFNULL, COALESCEISNULL, COALESCEIFNULL, COALESCECOALESCE
Concaténer du textea || ba + b, CONCAT()CONCAT()a || b, CONCAT()
Longueur d’un texteLENGTH()LEN()LENGTH(), CHAR_LENGTH()LENGTH()
Date du jourDATE('now')GETDATE()CURDATE()CURRENT_DATE

Les mêmes requêtes fonctionnent aussi, à quelques détails près, dans les entrepôts de données cloud comme Snowflake. Et si vous analysez ensuite vos résultats dans Power BI, sachez que le langage DAX reprend beaucoup de ces logiques de filtre et d’agrégation : notre guide sur le DAX dans Power BI fait le lien.

Comment progresser sur les requêtes SQL ?

La meilleure méthode consiste à pratiquer sur une base réaliste, en suivant cet ordre :

  1. Lecture simple : SELECT, AS, WHERE, ORDER BY, DISTINCT.
  2. Agrégation : GROUP BY, HAVING, fonctions COUNT, SUM, AVG.
  3. Jointures : INNER JOIN, LEFT JOIN, jointures multiples.
  4. Logique : CASE WHEN, gestion des NULL, fonctions de texte et de date.
  5. Structuration : sous-requêtes, UNION, CTE.
  6. Analyse : fonctions de fenêtre comme RANK, puis transactions et modifications.

Donnez-vous un objectif concret à chaque séance : « quels sont les dix clients les plus rentables ? », « quels produits ne se vendent plus depuis trois mois ? ». Écrire la requête qui répond à une vraie question est l’exercice le plus formateur.

Pour pratiquer avec des fichiers fournis, la formation vidéo pour débuter en SQL d’EspritAcadémique dure 2 h 15, ne demande aucun prérequis et s’appuie sur DB Browser for SQLite. Elle couvre notamment :

  • l’installation de l’outil, l’import de fichiers CSV et les notions de base de données ;
  • SELECT, WHERE, AND/OR et ORDER BY pour extraire et trier ;
  • les jointures, GROUP BY, HAVING, les calculs et le formatage de texte ;
  • INSERT, UPDATE, DELETE, la gestion des valeurs nulles et les transactions COMMIT et ROLLBACK ;
  • CASE WHEN, les sous-requêtes, UNION, les CTE avec WITH et les classements avec RANK.

Pour aller plus loin, avec SQL Server, la création de bases, les vues et les procédures stockées, suivez notre feuille de route pour apprendre SQL. Et si vos données viennent du web, notre guide de web scraping avec Python montre comment les collecter avant de les charger dans une base.

En résumé

Une requête SQL se construit toujours sur le même squelette : SELECT, FROM, JOIN, WHERE, GROUP BY, HAVING, ORDER BY. Maîtrisez d’abord le filtrage et le tri, puis les agrégations et les jointures, qui couvrent l’essentiel des besoins d’analyse. CASE WHEN, les CTE et RANK viennent ensuite pour les analyses plus fines. Gardez ces exemples sous la main, adaptez-les à vos tables, et testez toujours vos modifications dans une transaction.

Questions fréquentes

Quelle est la requête SQL la plus utilisée ?

La requête SELECT, qui sert à lire des données. Sa forme minimale est SELECT colonnes FROM table, à laquelle on ajoute WHERE pour filtrer, ORDER BY pour trier et GROUP BY pour agréger. La grande majorité des requêtes écrites par les analystes sont des SELECT ; INSERT, UPDATE et DELETE servent à modifier les données.

Quelle est la différence entre WHERE et HAVING ?

WHERE filtre les lignes individuelles avant tout regroupement : on ne peut pas y utiliser SUM ou COUNT. HAVING filtre les groupes créés par GROUP BY, après le calcul des agrégats : c'est là qu'on écrit une condition comme HAVING SUM(montant) > 1000. Une même requête peut combiner les deux.

Quelle est la différence entre INNER JOIN et LEFT JOIN ?

INNER JOIN ne renvoie que les lignes qui ont une correspondance dans les deux tables. LEFT JOIN renvoie toutes les lignes de la table de gauche, avec des valeurs NULL dans les colonnes de droite quand il n'y a pas de correspondance. Pour lister tous les clients, y compris ceux sans commande, il faut donc un LEFT JOIN.

Comment tester une requête SQL sans risque ?

Travaillez sur une copie de la base ou un fichier SQLite d'entraînement. Avant un UPDATE ou un DELETE, exécutez un SELECT avec la même clause WHERE pour vérifier les lignes concernées. Encadrez les modifications par BEGIN TRANSACTION, contrôlez le résultat, puis validez avec COMMIT ou annulez avec ROLLBACK.

Les requêtes SQL sont-elles identiques dans tous les logiciels ?

Le cœur du langage est standard : SELECT, WHERE, GROUP BY, jointures et sous-requêtes fonctionnent partout. Des différences existent sur certains détails : LIMIT en SQLite, MySQL et PostgreSQL contre TOP en SQL Server, IFNULL contre ISNULL, ou la concaténation de texte. COALESCE est standard et fonctionne dans tous ces systèmes.

Quel logiciel utiliser pour s'entraîner aux requêtes SQL ?

DB Browser for SQLite est idéal pour débuter : gratuit, léger, il ouvre une base contenue dans un simple fichier et permet d'importer des CSV. Pour un environnement d'entreprise, SQL Server avec SSMS ou PostgreSQL avec pgAdmin sont des choix courants. Les requêtes de base restent les mêmes d'un outil à l'autre.