SQL – CASE … WHEN … THEN …ELSE … END

Introduction

La commande SQL « CASE … WHEN … THEN …ELSE … END » permet d’utiliser des conditions de type « si / sinon » (cf. if / else) similaire à un langage de programmation pour réaliser des traitements avant affichage (SELECT) mais aussi mis à jour (UPDATE) …

Tous les exemples ci dessous ont été réalisés sur MySQL

Structure et Jeu de données

#création de la table jeu_donnee
CREATE TABLE IF NOT EXISTS `jeu_donnee` (
  `ID` int(10) unsigned NOT NULL,
  `nom` varchar(50) NOT NULL,
  `resume` tinytext NOT NULL,
  `prix` decimal(10,2) unsigned NOT NULL,
  `etat` enum('0','1') NOT NULL DEFAULT '0',
  `marque` varchar(50) DEFAULT NULL
);

ALTER TABLE `jeu_donnee`
  ADD PRIMARY KEY (`ID`);

ALTER TABLE `jeu_donnee`
  MODIFY `ID` int(10) unsigned NOT NULL AUTO_INCREMENT;

#insertion de données fictives
INSERT INTO `jeu_donnee` (`ID`, `nom`, `resume`, `prix`, `etat`, `marque`) VALUES
(1, 'Produit 1', 'Lorem ipsum dolor sit.', 10, '1', NULL),
(2, 'Produit 2', 'Cum doloremque deleniti officiis!', 15, '1', NULL),
(3, 'Produit 3', 'Eligendi, molestiae velit debitis!', 20, '0', 'marque 1'),
(4, 'Produit 4', 'Eaque quae unde soluta.', 2, '0', 'marque 1'),
(5, 'Produit 5', 'Expedita quam reprehenderit similique!', 35, '1', 'marque 2');
ID nom resume prix etat marque
1 Produit 1 Lorem ipsum dolor sit. 10 1 Null
2 Produit 2 Cum doloremque deleniti officiis! 15 1 Null
3 Produit 3 Eligendi, molestiae velit debitis! 20 0 marque 1
4 Produit 4 Eaque quae unde soluta. 2 0 marque 1
5 Produit 5 Expedita quam reprehenderit similique! 35 1 marque 2

exemple simple : personnaliser le résultat d’un SELECT

SELECT ID, nom, (CASE etat
	WHEN 1 THEN "Actif"
	ELSE "Inactif"
END) AS "lbl etat"
FROM jeu_donnee

Résultat

ID nom lbl etat
1 Produit 1 Actif
2 Produit 2 Actif
3 Produit 3 Inactif
4 Produit 4 Inactif
5 Produit 5 Actif

exemple en faisant un calcul

SELECT ID, nom, (CASE etat
	WHEN 1 THEN prix*1.2
	ELSE 0
END) AS "Prix produit TTC"
FROM jeu_donnee

Résultat

ID nom Prix produit TTC
1 Produit 1 0
2 Produit 2 0
3 Produit 3 24.0
4 Produit 4 2.4
5 Produit 5 0

exemple avec des AND et OR

SELECT ID, nom,
(CASE 
	WHEN etat = "1" AND Length(marque) > 0 THEN "Fiche complete"
	WHEN etat = "1" AND isnull(marque) OR Length(marque) = 0 THEN "Completer marque"
	ELSE "Inactif"
END) AS "lbl etat"
FROM jeu_donnee

Deux remarques :

  1. Attention les Enum sont des strings et non des number (d’où les doubles quotes)
  2. la longueur de Null n’est pas 0

Résultat

ID nom lbl etat
1 Produit 1 Completer marque
2 Produit 2 Completer marque
3 Produit 3 Inactif
4 Produit 4 Inactif
5 Produit 5 Fiche complete

exemple avec un regroupement COUNT et GROUP BY

SELECT 
	(CASE 
		WHEN etat = "1" AND Length(marque) > 0 THEN "Fiche complete"
		WHEN etat = "1" AND isnull(marque) OR Length(marque) = 0 THEN "A Completer marque"
		ELSE "Inactif"
	END) AS "lbl etat" ,
	COUNT(ID) AS NB
FROM jeu_donnee
GROUP BY (CASE 
		WHEN etat = "1" AND Length(marque) > 0 THEN "Fiche complete"
		WHEN etat = "1" AND isnull(marque) OR Length(marque) = 0 THEN "A Completer marque"
		ELSE "Inactif"
	END)

Résultat

lbl etat NB
A Completer marque 2
Fiche complete 1
Inactif 2

On peut remarque que les états sont classés par ordre alphabétique comme pour un SELECT Classique

documentation sur la commande CASE WHEN sur le net