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.

Présentation de l'expression CASE de PostgreSQL.

Il y a deux syntaxes possible pour l'expression conditionnelle CASE de PostgreSQL, la forme générale, et la forme simplifiée.

Forme générale

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).

Exemple 1

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)
Exemple 2

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)
Forme simplifiée

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.

Exemple de forme simplifiée

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)