CodeGym /Cours /SQL SELF /Fonctions GREATEST() et LEAST() et NULL

Fonctions GREATEST() et LEAST() et NULL

SQL SELF
Niveau 10 , Leçon 2
Disponible

Aujourd'hui, on plonge dans un sujet encore plus spécifique mais super important : les fonctions GREATEST() et LEAST(). Tu vas voir comment trouver les valeurs max et min parmi plusieurs colonnes, et surtout, comment NULL influence leur comportement.

Si t'as déjà cherché la chose la plus importante dans ta vie (l'amour, le job de rêve ou la meilleure recette de pizza), tu piges direct à quoi servent GREATEST() et LEAST(). Ces fonctions t'aident à trouver la plus grande ou la plus petite valeur dans une liste de trucs. Sauf qu'au lieu de la pizza, tu bosses avec des nombres, des dates, des chaînes de caractères et d'autres données dans PostgreSQL.

GREATEST()

GREATEST() te renvoie la plus grande valeur parmi celles que tu lui donnes.

Syntaxe :

GREATEST(value1, value2, ..., valueN)

LEAST()

LEAST() fait l'inverse : elle cherche la plus petite valeur.

Syntaxe :

LEAST(value1, value2, ..., valueN)

Exemple :

Imaginons qu'on a une table students_scores où sont stockées les notes des étudiants pour trois exams :

student_id exam_1 exam_2 exam_3
1 85 90 82
2 NULL 76 89
3 94 NULL 88

Utilisation de GREATEST() et LEAST() :

SELECT
    student_id,
    GREATEST(exam_1, exam_2, exam_3) AS highest_score,
    LEAST(exam_1, exam_2, exam_3) AS lowest_score
FROM students_scores;

Résultat :

student_id highest_score lowest_score
1 90 82
2 89 NULL
3 94 NULL

Comment NULL influence GREATEST() et LEAST()

Maintenant, on arrive à la partie la plus fun. Dans la table, tu peux avoir des valeurs NULL. Et comme tu le sais déjà, NULL c'est cette entité mystérieuse qui veut dire "pas de donnée" ou "valeur inconnue". Voyons ce qui se passe si NULL se retrouve dans GREATEST() ou LEAST() dans PostgreSQL.

Comportement de NULL :

Dans PostgreSQL, les fonctions GREATEST() et LEAST() ont un comportement spécial : elles ignorent les valeurs NULL quand elles cherchent la valeur max ou min parmi leurs arguments. Important : Le seul cas où ces fonctions renvoient NULL, c'est si tous leurs arguments sont NULL.

Exemple :

SELECT
    GREATEST(10, 20, NULL, 5) AS greatest_value,
    LEAST(10, 20, NULL, 5) AS least_value;

Résultat :

greatest_value least_value
20 5

Comme tu vois, NULL a été ignoré, et les fonctions ont renvoyé les valeurs max et min parmi celles présentes (10, 20, 5).

Et voilà un exemple où tous les arguments sont NULL :

Exemple :

SELECT
    GREATEST(NULL, NULL) AS greatest_nulls,
    LEAST(NULL, NULL) AS least_nulls;

Résultat :

greatest_nulls least_nulls
NULL NULL

Comment éviter les soucis avec NULL ?

Même si PostgreSQL ignore NULL par défaut, parfois tu veux un autre comportement. Par exemple, tu veux que NULL soit considéré comme une valeur précise (genre 0 ou une autre valeur par défaut) quand tu cherches le max/min. Dans ce cas, tu peux utiliser la fonction COALESCE().

La fonction COALESCE(arg1, arg2, ...) renvoie le premier argument qui n'est pas NULL dans sa liste. Ça te permet de remplacer NULL par une valeur qui a du sens avant de passer à GREATEST() ou LEAST().

Exemple 1 : Remplacer NULL par 0

Imaginons qu'on veut considérer qu'une note absente (NULL) vaut 0. On peut utiliser COALESCE() pour mettre une valeur par défaut.

Voici notre table de départ :

student_id exam_1 exam_2 exam_3
1 90 85 82
2 NULL 89 NULL
3 NULL NULL 94

Requête :

SELECT
    student_id,
    GREATEST(
        COALESCE(exam_1, 0), 
        COALESCE(exam_2, 0), 
        COALESCE(exam_3, 0)
    ) AS highest_score,
    LEAST(
        COALESCE(exam_1, 0), 
        COALESCE(exam_2, 0), 
        COALESCE(exam_3, 0)
    ) AS lowest_score
FROM students_scores;

Résultat :

student_id highest_score lowest_score
1 90 82
2 89 0
3 94 0

Exemple 2 : Remplacer NULL par la valeur d'une autre colonne

Parfois, au lieu d'une valeur fixe (genre 0), tu veux mettre la valeur d'une autre colonne. Par exemple, si exam_3 manque, tu veux utiliser la valeur de exam_1.

SELECT
    student_id,
    GREATEST(
        exam_1, 
        exam_2, 
        COALESCE(exam_3, exam_1)
    ) AS highest_score
FROM students_scores;

Imaginons qu'on a cette table :

student_id exam_1 exam_2 exam_3
1 90 85 82
2 NULL 89 NULL
3 70 NULL NULL

Résultat de la requête :

student_id highest_score
1 90
2 89
3 70

Cas pratiques

Cas 1 : Trouver la remise maximale

order_id discount_1 discount_2 discount_3
101 5 10 7
102 NULL 3 8
103 15 NULL NULL
104 NULL NULL NULL

Tu bosses avec la table orders, où chaque commande peut avoir trois types de remise différents. Tu dois trouver la remise max pour chaque commande.

SELECT
    order_id,
    GREATEST(discount_1, discount_2, discount_3) AS max_discount
FROM orders;

Résultat :

order_id max_discount
101 10
102 8
103 15
104 NULL

Cas 2 : Trouver le prix minimal d'un produit

Dans la table products, tu as les prix des produits dans trois devises (USD, EUR, GBP). Ton but : trouver le prix le plus bas pour chaque produit.

product_id price_usd price_eur price_gbp
1 100 95 80
2 NULL 150 140
3 200 NULL NULL
4 NULL NULL NULL
SELECT
    product_id,
    LEAST(price_usd, price_eur, price_gbp) AS lowest_price
FROM products;
product_id lowest_price
1 80
2 140
3 200
4 NULL

Si tous les prix sont NULL, le résultat sera aussi NULL

Erreurs classiques avec GREATEST() et LEAST()

Erreur 1 : Résultat inattendu à cause de NULL.

On a déjà vu plus haut comment NULL influence GREATEST() et LEAST() dans PostgreSQL. L'erreur principale, c'est que les gens qui ont l'habitude d'autres SGBD (où un seul NULL "contamine" tout le résultat) s'attendent à la même chose dans PostgreSQL.

Comment ça se manifeste : Tu peux croire à tort que si y'a un NULL dans la liste des arguments, la fonction va toujours renvoyer NULL. Du coup, tu risques d'utiliser COALESCE() partout pour rien, ce qui complique la requête et peut la ralentir, alors que dans ton cas NULL devrait juste être ignoré.

Erreur 2 : Utiliser GREATEST() et LEAST() avec des types incompatibles.

Les fonctions GREATEST() et LEAST() sont faites pour comparer des valeurs du même type de données ou des types qui peuvent être convertis implicitement entre eux. Si tu essaies de comparer des types totalement différents et incompatibles, tu vas avoir une erreur.

Comment ça se manifeste : Tu vas recevoir un message d'erreur qui te dit que les types de données sont incompatibles.

Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION