SQL CASE WHEN : la logique conditionnelle dans les requêtes
Leçon 3.5 · Temps de lecture : ~7 min · Exercices pratiques ↓
L'expression SQL CASE ajoute une logique si-alors-sinon à une requête : elle vérifie des conditions dans l'ordre et renvoie la valeur de la première qui est vraie. Dans cette leçon, vous apprendrez les deux formes de CASE, comment créer des catégories et des libellés dans SELECT, comment trier selon une priorité personnalisée et comment utiliser CASE dans WHERE.
Les fonctions des leçons précédentes transforment chaque ligne de la même façon. Souvent, la règle dépend des données : un paiement de moins de 2 $ est « faible », de plus de 6 $ « élevé » ; une location sans date de retour est « non rendue ». CASE vous permet d'écrire ces règles directement en SQL au lieu de les gérer dans le code de l'application.
Syntaxe de CASE
CASE a deux formes.
CASE de recherche
Chaque WHEN contient sa propre condition. C'est la forme la plus souple et la plus courante :
CASE
WHEN condition1 THEN result1
WHEN condition2 THEN result2
ELSE default_result
END
CASE simple
Une expression est comparée à une liste de valeurs :
CASE expression
WHEN value1 THEN result1
WHEN value2 THEN result2
ELSE default_result
END
Comment CASE est évalué
- Les conditions sont vérifiées de haut en bas.
- Le résultat de la première condition vraie est renvoyé ; les autres ne sont pas vérifiées.
- Si aucune condition n'est vraie, la valeur d'
ELSEest renvoyée. - S'il n'y a pas d'
ELSE, le résultat estNULL.
CASE est une expression, pas une instruction séparée : il renvoie une valeur et peut être utilisé partout où une valeur est permise, dans SELECT, WHERE ou ORDER BY.
CASE dans SELECT : catégories et libellés
Niveaux de paiement
SELECT payment_id,
amount,
CASE
WHEN amount < 2 THEN 'Low'
WHEN amount < 6 THEN 'Medium'
ELSE 'High'
END AS payment_level
FROM payment
LIMIT 10;
Résultat : dix paiements, chacun avec un niveau : moins de 2 $ « Low », de 2 $ à moins de 6 $ « Medium », 6 $ et plus « High ».
L'ordre des conditions compte. Un paiement de 1 $ satisfait aussi amount < 6, mais il reçoit « Low » parce que la première branche correspondante l'emporte. Grâce à cela, la deuxième condition n'a pas besoin de borne inférieure.
Un statut lisible
SELECT rental_id,
rental_date,
CASE
WHEN return_date IS NULL THEN 'Not returned'
ELSE 'Returned'
END AS rental_status
FROM rental
ORDER BY rental_date DESC
LIMIT 10;
Résultat : les dernières locations avec un statut textuel au lieu d'une date de retour vide ou remplie.
CASE simple pour des codes
La forme simple est pratique quand une colonne contient des codes :
SELECT title,
rating,
CASE rating
WHEN 'G' THEN 'General audiences'
WHEN 'PG' THEN 'Parental guidance'
WHEN 'PG-13' THEN 'Parents strongly cautioned'
WHEN 'R' THEN 'Restricted'
ELSE 'Adults only'
END AS rating_description
FROM film
LIMIT 10;
Résultat : les films avec une description lisible de leur classification.
CASE dans ORDER BY : un ordre de tri personnalisé
L'ordre alphabétique des codes de classification (G, NC-17, PG, PG-13, R) ne correspond pas à leur signification. CASE transforme chaque code en un numéro de priorité :
SELECT title, rating
FROM film
ORDER BY CASE rating
WHEN 'G' THEN 1
WHEN 'PG' THEN 2
WHEN 'PG-13' THEN 3
WHEN 'R' THEN 4
ELSE 5
END,
title;
Résultat : les films de la classification la plus douce à la plus stricte ; dans une même classification, par titre.
La même technique place les lignes importantes en tête :
SELECT rental_id, rental_date, return_date
FROM rental
ORDER BY CASE WHEN return_date IS NULL THEN 0 ELSE 1 END,
rental_date DESC
LIMIT 20;
Résultat : d'abord les locations non rendues, puis les autres, les plus récentes en premier dans chaque groupe.
CASE dans WHERE
CASE peut renvoyer une valeur pour une condition, par exemple un seuil qui dépend d'une autre colonne :
SELECT payment_id, staff_id, amount
FROM payment
WHERE amount >= CASE
WHEN staff_id = 1 THEN 5
ELSE 3
END
LIMIT 10;
Résultat : les paiements d'au moins 5 $ pour l'employé 1 et d'au moins 3 $ pour les autres.
La plupart de ces filtres peuvent aussi s'écrire avec AND et OR : WHERE (staff_id = 1 AND amount >= 5) OR (staff_id <> 1 AND amount >= 3). Choisissez la version la plus lisible : pour deux branches, c'est souvent OR ; pour beaucoup de branches, CASE.
Conseils pratiques
- Écrivez toujours
ELSE. Sans lui, les valeurs inattendues deviennentNULL, et ces lignes passent facilement inaperçues. - Renvoyez un seul type de données. Mélanger texte et nombres dans les branches entraîne des conversions implicites et des surprises.
- Ordonnez les conditions du plus spécifique au plus général. La première branche vraie l'emporte.
- Dans la leçon 4.4, vous utiliserez
CASEà l'intérieur des fonctions d'agrégation pour compter des lignes par catégorie en une seule requête.
Points clés :
CASErenvoie le résultat de la première conditionWHENvraie, ouELSEsi aucune ne l'est.- Le
CASEde recherche vérifie n'importe quelles conditions ; leCASEsimple compare une expression à des valeurs. - Sans
ELSE, le résultat estNULL. - Dans
SELECT,CASEcrée des catégories et des libellés lisibles. - Dans
ORDER BY, il définit un ordre de tri personnalisé ; dansWHERE, il peut faire dépendre un filtre d'autres colonnes.
Questions fréquentes
Quelle est la différence entre CASE simple et CASE de recherche ?
Le CASE simple compare une expression à une liste de valeurs : CASE rating WHEN 'G' THEN .... Le CASE de recherche vérifie une condition distincte dans chaque branche : CASE WHEN amount < 2 THEN .... Le CASE de recherche peut tout ce que fait la forme simple, plus les plages, les tests de NULL et les conditions sur plusieurs colonnes.
Que renvoie CASE si aucune condition n'est vraie et qu'il n'y a pas d'ELSE ?
NULL. Pour éviter les surprises, ajoutez toujours une branche ELSE avec une valeur par défaut explicite.
Existe-t-il une fonction IF en SQL ?
CASE est la méthode standard. MySQL et MariaDB ont aussi IF(condition, value_if_true, value_if_false), et SQL Server a IIF(), mais ces fonctions ne sont pas portables.