Les expressions 'CASE' dans PostgreSQL
publication : May 2021
Les expressions conditionnelles, tel que les blocs if-else et les CASE, sont l'un des éléments les plus fondamentaux de tout paradigme de programmation.
Il y a deux syntaxes possible pour l'expression conditionnelle CASE de PostgreSQL, la forme générale, et la forme simplifiée.
La syntaxe générale de l'expression conditionnelle CASE est :
CASE
WHEN condition_1 THEN result_1
WHEN condition_2 THEN result_2
...
ELSE result_else
END
Dans cette syntaxe, chaque condition (condition_1, condition_2, ...) est une expression booléenne qui retourne vrai ou faux (true, false).
Lorsque un test de condition retourne faux, l'expression CASE évalue la condition suivante jusqu'à ce qu'une condition retourne vraie et que le résultat associé (resultat_1, résultat_2,...) soit retourné.
Si aucune condition n'est vérifié, alors le résultat de la branche ELSE (sinon) sera retourné (result_else).
Dans le cas de vente de produits, on doit lister les montants, avec une mention "à vérifier" lorsque qu'ils sont supérieurs à 350€ par exemple.
On utilise le contenu suivant :
tutorial=# select * from production.detail_facture;
client_id | facture_ref | facture_ligne | article_id | vente_qte | article_price
-----------+-------------+---------------+------------+-----------+---------------
112 | F0121 | 1 | 1004 | 4 | 35.30
112 | F0121 | 2 | 1002 | 4 | 34.30
263 | F0221 | 1 | 1004 | 12 | 32
263 | F0221 | 2 | 1006 | 4 | 160.0
98 | F0321 | 1 | 1001 | 1 | 34.30
320 | F0421 | 1 | 1004 | 12 | 32
320 | F0421 | 2 | 1005 | 1 | 130.0
328 | F0521 | 1 | 1004 | 4 | 35.30
328 | F0521 | 2 | 1002 | 4 | 34.30
328 | F0521 | 3 | 1004 | 12 | 32
328 | F0521 | 4 | 1006 | 2 | 160.0
66 | F0621 | 1 | 1006 | 6 | 160.0
54 | F0721 | 1 | 1004 | 12 | 32.0
54 | F0721 | 2 | 1006 | 2 | 160.0
La requête utilisée est la suivante :
select facture_ref, vente_qte*article_price as Total,
CASE
WHEN vente_qte*article_price >= 350 THEN 'A Vérifier'
WHEN vente_qte*article_price < 350 THEN 'Sans vérification'
END as "Vérification"
from production.detail_facture
order by 3;
On obtient :
facture_ref | total | Vérification
-------------+--------+-------------------
F0421 | 384 | A Vérifier
F0521 | 384 | A Vérifier
F0221 | 640.0 | A Vérifier
F0621 | 960.0 | A Vérifier
F0721 | 384.0 | A Vérifier
F0221 | 384 | A Vérifier
F0521 | 320.0 | Sans vérification
F0121 | 141.20 | Sans vérification
F0721 | 320.0 | Sans vérification
F0121 | 137.20 | Sans vérification
F0321 | 34.30 | Sans vérification
F0421 | 130.0 | Sans vérification
F0521 | 141.20 | Sans vérification
F0521 | 137.20 | Sans vérification
(14 rows)
On souhaite avoir par trimestre le nombre de facture sur l'année 2021 avec le contenu suivant :
tutorial=# select * from production.facture;
client_id | facture_ref | facture_date
-----------+-------------+--------------
112 | F0121 | 2021-03-15
263 | F0221 | 2021-04-12
98 | F0321 | 2021-04-25
320 | F0421 | 2021-04-30
328 | F0521 | 2021-05-02
66 | F0621 | 2021-05-10
54 | F0721 | 2021-05-25
(7 rows)
select
SUM ( CASE WHEN EXTRACT(YEAR FROM facture_date)=2021 AND EXTRACT(MONTH FROM facture_date) in (1,2,3) THEN 1 ELSE 0 END ) as "2021 Q1",
SUM ( CASE WHEN EXTRACT(YEAR FROM facture_date)=2021 AND EXTRACT(MONTH FROM facture_date) in (4,5,6) THEN 1 ELSE 0 END ) as "2021 Q2",
SUM ( CASE WHEN EXTRACT(YEAR FROM facture_date)=2021 AND EXTRACT(MONTH FROM facture_date) in (7,8,9) THEN 1 ELSE 0 END ) as "2021 Q3",
SUM ( CASE WHEN EXTRACT(YEAR FROM facture_date)=2021 AND EXTRACT(MONTH FROM facture_date) in (10,11,12) THEN 1 ELSE 0 END ) as "2021 Q4"
FROM production.facture;
On obtient:
2021 Q1 | 2021 Q2 | 2021 Q3 | 2021 Q4
---------+---------+---------+---------
1 | 6 | 0 | 0
(1 row)
La syntaxe simplifiée de l'expression conditionnelle CASE est :
CASE expression
WHEN value_1 THEN result_1
WHEN value_2 THEN result_2
[WHEN ...]
ELSE
else_result
END
Dans sa forme simplifié, les conditions ne portent que sur les valeurs possibles de l'expression.
Le CASE évalue d'abord l'expression et compare le résultat avec chaque valeur( valeur_1, valeur_2, ...) dans les clauses WHEN de manière séquentielle jusqu'à ce qu'il trouve la correspondance.
Dès que le résultat de l'expression est égal à une valeur (valeur_1, valeur_2, etc.) dans une clause WHEN, le CASE renvoie le résultat correspondant dans la clause THEN.
Si CASE ne trouve aucune correspondance, il renvoie le résultat else_result dans la clause qui suit le ELSE, ou la valeur NULL si le ELSE n'est pas disponible.
Avec le contenu suivant d'une table client :
tutorial=# select * from production.client;
client_id | client_name | client_categorie
-----------+-------------+------------------
112 | TopZe | P
54 | KelKom | P
65 | Finance | A
263 | Martin | D
66 | Impots | A
98 | Durand | D
320 | Dupond | D
328 | Ste Fast | P
(8 rows)
Le code 'client_categorie' contien 'A','P','D', pour respectivement 'Administration', 'Professionnel', 'Divers'.
Pour obtenir une liste contenant la description de la catégorie, on utilise le code SQL suivant :
Select client_id, client_name,
CASE client_categorie
WHEN 'A' THEN 'Administration'
WHEN 'P' THEN 'Professionnel'
WHEN 'D' THEN 'Divers'
ELSE 'Hors catégorie'
END
from production.client;
On obtient:
client_id | client_name | case
-----------+-------------+----------------
112 | TopZe | Professionnel
54 | KelKom | Professionnel
65 | Finance | Administration
263 | Martin | Divers
66 | Impots | Administration
98 | Durand | Divers
320 | Dupond | Divers
328 | Ste Fast | Professionnel
(8 rows)