CodeGym /Cours /SQL SELF /Expressions conditionnelles : CASE WHEN ... THEN ... ELSE...

Expressions conditionnelles : CASE WHEN ... THEN ... ELSE ... END

SQL SELF
Niveau 10 , Leçon 0
Disponible

Tu as sûrement déjà croisé des expressions conditionnelles dans des langages de programmation : if-else, switch-case et ce genre de trucs. En SQL, il y a son propre outil pour bosser avec les conditions : c'est l'expression CASE. Elle te permet de prendre des décisions direct dans les requêtes : si la condition est vraie, tu fais un truc, sinon tu fais autre chose.

La construction CASE est super utile quand tu bosses avec des données qui peuvent contenir des valeurs NULL. Le syntaxe est simple, genre anti-sèche, regarde :

CASE
    WHEN condition1 THEN résultat1
    WHEN condition2 THEN résultat2
    ...
    ELSE résultat_par_défaut
END

Logique, non ? "Si c'est comme ça, fais ça, sinon fais autre chose". Facile à retenir : "WHEN — c'est si, THEN — c'est quoi faire, ELSE — c'est quoi faire si rien ne correspond".

Exemple : classification des produits

Imagine qu'on a une table products avec une colonne price, et on veut répartir les produits en groupes selon leur prix.

id name price
1 Magic Wand 120
2 Potion Set 45
3 Crystal Ball 75
4 Enchanted Map NULL
5 Broomstick 99
6 Spell Book 180
SELECT
    name AS product_name,
    price,
    CASE
        WHEN price IS NULL THEN 'Inconnu'
        WHEN price < 50 THEN 'Économique'
        WHEN price BETWEEN 50 AND 100 THEN 'Standard'
        ELSE 'Premium'
    END AS price_category
FROM products;

Qu'est-ce qui se passe ici ?

  1. Si le prix price du produit n'est pas renseigné NULL, on affiche la catégorie comme 'Inconnu'.
  2. Si le prix est inférieur à 50, le produit est considéré comme économique 'Économique'.
  3. Si le prix est entre 50 et 100, il tombe dans la catégorie 'Standard'.
  4. Tout le reste — c'est des produits premium 'Premium'.

Voilà le résultat :

product_name price price_category
Magic Wand 120 Premium
Potion Set 45 Économique
Crystal Ball 75 Standard
Enchanted Map NULL Inconnu
Broomstick 99 Standard
Spell Book 180 Premium

SQL, comme un magicien, lit les lignes de la table products, applique la logique à chaque ligne et classe tout ça malin.

Travailler avec NULL dans CASE WHEN

Souvent, il y a des valeurs manquantes dans les données (coucou NULL), et il faut les remplacer par autre chose. Par exemple, on a une table users avec une colonne email, et pour les utilisateurs sans email, on veut afficher 'Non renseigné'.

user_id name email
1 Alex Lin alex@example.com
2 Maria Chi NULL
3 Anna Song anna@magic.com
4 Otto Art NULL
5 John Smith john@wizard.org
SELECT
    user_id,
    name,
    CASE
        WHEN email IS NULL THEN 'Non renseigné'
        ELSE email
    END AS email_address
FROM users;
user_id name email_address
1 Alex Lin alex@example.com
2 Maria Chi Non renseigné
3 Anna Song anna@magic.com
4 Otto Art Non renseigné
5 John Smith john@wizard.org

SQL ici fait le chaman : il redonne vie aux lignes à moitié vides. Si l'email manque, il le remplace par 'Non renseigné'. Si l'email existe — il le garde tel quel.

Expressions conditionnelles avec des nombres

Parfois, il ne s'agit pas juste de remplacer des valeurs, mais de construire une nouvelle logique. Par exemple, imaginons qu'on a une table students avec les colonnes score (note) et name.

name score
Alex Lin 95
Maria Chi 82
Anna Song 48
Otto Art NULL
John Smith 67
Zoe Black 30

On veut évaluer les étudiants comme "Excellent", "Passable" et "Échec", selon leurs notes.

SELECT
    name AS student_name,
    score,
    CASE
        WHEN score IS NULL THEN 'Pas de note'
        WHEN score >= 90 THEN 'Excellent'
        WHEN score >= 50 THEN 'Passable'
        ELSE 'Échec'
    END AS performance_category
FROM students;
student_name score performance_category
Alex Lin 95 Excellent
Maria Chi 82 Passable
Anna Song 48 Échec
Otto Art NULL Pas de note
John Smith 67 Passable
Zoe Black 30 Échec

SQL distribue gentiment les étudiants, comme un examinateur sévère : 90 points et plus — c'est "Excellent", à partir de 50 — "Passable". Et si ça ne suffit pas... tu vois le délire.

Groupement et gestion des NULL

Travailler avec des groupes de données — c'est encore un domaine où CASE WHEN brille. Imagine qu'on a une table orders, et on veut compter le nombre total de commandes par statut, y compris celles avec un statut NULL.

order_id status
1 Completed
2 Pending
3 NULL
4 Shipped
5 Completed
6 NULL
7 Pending
8 Completed
9 Shipped
10 NULL
SELECT
    CASE
        WHEN status IS NULL THEN 'Aucun statut'
        ELSE status
    END AS order_status,
    COUNT(*)
FROM orders
GROUP BY 
    CASE
        WHEN status IS NULL THEN 'Aucun statut'
        ELSE status
    END;

Cette requête gère proprement les statuts NULL et met 'Aucun statut' à la place, puis compte le nombre total de commandes dans chaque groupe. Voilà le résultat :

order_status count
Completed 3
Pending 2
Shipped 2
Aucun statut 3

Cas pratiques : "Tours de magie" avec CASE WHEN

Exemple 1 : Tri en tenant compte des NULL

Parfois, il faut afficher les valeurs NULL soit en premier, soit en dernier dans une liste triée. C'est souvent utilisé, par exemple, dans les listes de tâches où les tâches prioritaires doivent être en haut, et celles sans priorité (NULL) à la fin.

task_id task_name priority
1 Fix bugs 1
2 Update documentation 3
3 Plan sprint NULL
4 Code review 2
5 Organize meeting NULL
6 Deploy release 1
SELECT
    task_name,
    priority,
    CASE
        WHEN priority IS NULL THEN 1
        ELSE 0
    END AS priority_sort
FROM tasks
ORDER BY priority_sort ASC, priority ASC;

Ici, on a ajouté une colonne "virtuelle" priority_sort qui met les NULL tout en bas, et le reste est trié par ordre croissant.

task_name priority priority_sort
Deploy release 1 0
Fix bugs 1 0
Code review 2 0
Update documentation 3 0
Plan sprint NULL 1
Organize meeting NULL 1

Exemple 2 : Calculs avec NULL

Maintenant, imagine qu'on calcule le montant final d'une commande dans la table orders, où la colonne discount peut être NULL si y'a pas de remise.

order_id total_price discount
101 100 10
102 200 NULL
103 150 15
104 120 NULL
105 80 5

On doit remplacer NULL par 0 pour que le calcul ne parte pas en vrille.

SELECT 
    order_id,
    total_price,
    discount,
    total_price - 
    CASE
        WHEN discount IS NULL THEN 0
        ELSE discount
    END AS final_price
FROM orders;
order_id total_price discount final_price
101 100 10 90
102 200 NULL 200
103 150 15 135
104 120 NULL 120
105 80 5 75

Ce petit tour de magie avec CASE nous garantit que NULL ne va pas casser les calculs.

Pour orderid = 101 : discount = 10. finalprice = 100 - 10 = 90. Pour orderid = 102 : discount = NULL. CASE renvoie 0. finalprice = 200 - 0 = 200. Pour orderid = 103 : discount = 15. finalprice = 150 - 15 = 135. Pour orderid = 104 : discount = NULL. CASE renvoie 0. finalprice = 120 - 0 = 120. Pour orderid = 105 : discount = 5. finalprice = 80 - 5 = 75.

Exemple 3 : Affichage des statuts utilisateurs

Dans la vie de tous les jours, on doit souvent afficher le statut d'un utilisateur (genre "Actif" ou "En attente") ou signaler l'absence de données. Par exemple, dans la table users il y a une colonne last_login qui stocke la date de dernière connexion.

user_id name last_login
1 Alex Lin 2024-12-10
2 Maria Chi 2025-04-20
3 Anna Song NULL
4 Otto Art 2025-05-01
5 Liam Park 2025-05-25
SELECT
    user_id,
    name,
    CASE
        WHEN last_login IS NULL THEN 'Jamais connecté'
        WHEN last_login < CURRENT_DATE - INTERVAL '30 days' THEN 'Inactif'
        ELSE 'Actif'
    END AS user_status
FROM users;

Avec cette requête, le système d'admin prend vie : les utilisateurs jamais connectés sont "Jamais connecté", ceux qui ne sont pas venus depuis longtemps sont "Inactif". Les autres sont actifs !

user_id name user_status
1 Alex Lin Inactif
2 Maria Chi Inactif
3 Anna Song Jamais connecté
4 Otto Art Inactif
5 Liam Park Actif

Erreurs fréquentes et comment les éviter

Oublier ELSE : Si tu n'ajoutes pas ELSE, SQL va juste renvoyer NULL si aucune condition n'est remplie. C'est pas toujours ce que tu veux. Donc, mieux vaut toujours mettre ELSE, même si t'es sûr d'avoir tout couvert.

CASE
    WHEN condition THEN résultat
    -- ELSE 'Valeur par défaut' -- n'oublie pas !
END

Conditions complexes sans parenthèses : Si t'as plusieurs conditions avec AND, OR ou NOT, mets toujours des parenthèses. Sinon ta requête peut "penser" de travers.

CASE
    WHEN (column1 IS NOT NULL AND column2 > 5) THEN 'Valide'
    ELSE 'Invalide'
END

Travailler avec NULL : Rappelle-toi que NULL n'est jamais égal (=) à quoi que ce soit. Par exemple :

CASE
    WHEN column = NULL THEN 'Nope!' -- Erreur !
    WHEN column IS NULL THEN 'Correct !' -- Ça c'est bon.
END
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION