Aller au menu - Aller au contenu

[Plan du site] Vous êtes ici --- > Le Site du Zér0 > Les tutoriels > Non-Officiels > Site Web > PHP > Base de données > Lecture du tutoriel

Traitement des "NULL"s

Avatar
Auteur : Shepard
Créé : le 14/04/2006 15:37:58
Modifié : le 02/05/2007 11:15:50
Noter et commenter ce tutoriel
Imprimer ce tutoriel
Vous vous apprêtez à lire un tutoriel rédigé par un membre de ce site. Malgré tout le soin que ce membre a pu apporter au tutoriel, nous ne pouvons pas garantir que les informations contenues sur cette page sont exactes à 100%. Merci de garder cela en tête lorsque vous lirez cette page ;o)
Voici un autre chapitre intéressant : le traitement des valeurs nulles, autrement dit le traitement d'une absence de valeurs !

Encore une fois, peu de développeurs se servent de cette fonctionnalité ! Pourtant les valeurs nulles sont pratiquement indispensables dans une base de données. L'exemple le plus flagrant est un profil dans un espace membre : la plupart des codeurs mettent une chaîne vide ( '' ) pour indiquer qu'il n'y a pas de valeur, alors qu'il serait plus simple de mettre un simple NULL, qui peut être traité beaucoup plus facilement par la suite dans les requêtes SELECT grâce aux fonctions que nous verrons dans ce chapitre. :)

Je vous laisse lire tout ça, bonne lecture !
Sommaire du chapitre :
Chapitre précédent Sommaire Chapitre suivant

Spécificités des valeurs nulles

La valeur NULL n'est pas une valeur comme les autres. En général, on la considère comme une valeur à problèmes, mais en fait elle est très pratique à partir du moment où on sait l'utiliser.

Notamment, ceux qui utilisent les jointures se plaignent qu'on ne peut récupérer les lignes où la réfèrence est nulle, c'est simplement parce qu'ils utilisent LEFT JOIN au lieu de RIGHT JOIN, mais ça c'est l'objet d'un autre chapitre. ^^


Les valeurs NULL, comme je vous le disais, sont spéciales. Par exemple, on ne peut pas les comparer. Pour comprendre ce principe, créons une table exemple :

Code : SQL
1
2
CREATE TABLE ex_null ( id INT AUTO_INCREMENT, points INT DEFAULT NULL, PRIMARY KEY ( id ) );
INSERT INTO ex_null ( points ) VALUES ( 135 ), ( 3484 ), ( DEFAULT ), ( DEFAULT ), ( 0 ), ( DEFAULT );


Dans cette table, les NULL représentent ceux qui n'ont jamais gagné ni perdu de points. Les 0 représentent ceux qui ont déjà gagné des points, mais les ont reperdus.

Un autre façon de faire cette table aurait été d'ajouter une colonne "a_deja_joue", mais elle est totalement inutile dans le sens où un NULL nous permet d'avoir cette information plus facilement sans colonne supplémentaire.

Essayons de récupérer les lignes de ceux qui n'ont jamais joué:

Code : SQL
1
SELECT id, points FROM ex_null WHERE points = NULL;

Image utilisateur


Euh... o_O MySQL est devenu bigleu ?? :waw:


Non, c'est juste que les NULL ne peuvent pas être comparés à l'aide du signe "=". Et encore, MySQL est gentil : tout autre SGBDR aurait renvoyé une erreur (ou le devrait, tout comme MySQL).

Pour savoir si une valeur est nulle, il faut utiliser l'opérateur IS NULL :

Code : SQL
1
SELECT id, points FROM ex_null WHERE points IS NULL;

Image utilisateur


C'est déjà mieux, non ? :p :)

Attention également aux opérations comprenant des valeurs nulles : 1 + NULL = NULL en SQL !
A noter les opérations avec OR : x OR NULL = x SAUF SI x = NULL ou x = 0 !

Les fonctions de traitement des valeurs nulles

COALESCE



Fonction très pratique : COALESCE prend une liste d'arguments aussi longue que l'on veut (pas trop quand même :p ), et renvoie la première valeur non nulle passée en argument :

Code : SQL
1
SELECT COALESCE(NULL, 0);

Renvoie 0.

Donc dans notre table d'essai, pour renvoyer 0 au lieu de NULL, on pourrait faire comme ça :

Code : SQL
1
SELECT id, COALESCE(points, 0) FROM ex_null;

Image utilisateur


Un exemple de la praticité de la fonction COALESCE :

Code : SQL
1
SELECT id, COALESCE(points, 'N''a jamais joue') AS points FROM ex_null;

Image utilisateur


Essayez donc d'obtenir un tel résultat si facilement avec une colonne "a_deja_joue" supplémentaire. ;) :)

IFNULL



IFNULL est une fonction assez... spéciale et plutôt compliquée à comprendre au début, mais rassurez-vous : on s'y fait tous. :p :)

IFNULL prend deux paramètres.

Si le premier paramètre est NULL, alors le deuxième paramètre est renvoyé.
Si le premier paramètre n'est pas NULL, alors c'est lui-même qui est renvoyé.

Compris ? :p

Relisez ça une paire de fois, et passez à la suite une fois que vous serez sûr d'avoir compris. :)

On va simuler une colonne a_deja_joue qui vaudra 0 si les points sont égaux à NULL, sinon 1.

Pour cela, on va commencer par utiliser IFNULL(points, 0)

Code : SQL
1
SELECT id, IFNULL(points, 0) AS a_deja_joue FROM ex_null;

Image utilisateur


Ainsi, si points est NULL, on aura 0, sinon on aura [points].

Pour le 0, c'est bon, mais nous, on veut 1, on ne veut pas points, car si points vaut 0 (comme l'enregistrement ayant pour id 5), notre système ne fonctionnera pas. On va donc diviser le résultat du IFNULL par COALESCE(points, 1). Ainsi on aura soit 1 (points <> 0 => points/points = 1), soit 0 (points = NULL => 0 / 1 = 0), soit NULL (points = 0 => 0 / 0 = NULL en SQL).

Code : SQL
1
SELECT id, IFNULL(points, 0) / COALESCE(points, 0) AS a_deja_joue FROM ex_null;

Image utilisateur


Ici, on peut améliorer un truc : comme vous le voyez, on obtient 1.0000 et 0.0000, pas super joli, pour obtenir 1 et 0 il suffit d'utiliser l'opérateur DIV vu au second chapitre. :)

Code : SQL
1
SELECT id, IFNULL(points, 0) DIV COALESCE(points, 0) AS a_deja_joue FROM ex_null;

Image utilisateur


Il reste un tout petit problème : les NULL (points = 0) doivent être transformés en 1. Pour cela, évidemment, rien de plus simple, il suffit d'utiliser, une fois de plus, la fonction COALESCE qui englobera cette fois toute la division :

Code : SQL
1
SELECT id, points, COALESCE(IFNULL(points, 0) DIV COALESCE(points, 1), 1) AS a_deja_joue FROM ex_null;

Image utilisateur


Assez sympa non ? Bon j'admets que ce n'était peut-être pas super super simple à comprendre, mais en y allant étape par étape, ça a du bien se passer, enfin j'espère. :)

En fait, il existe une méthode beaucoup plus simple pour obtenir cela, l'inconvénient, c'est qu'elle n'est valable qu'avec MySQL. :( Je vous déconseille vraiment de l'utiliser, surtout si vous faites des calculs à base du résultat, voici cette autre requête :

Code : SQL
1
SELECT id, points IS NULL AS a_deja_joue FROM ex_null;


Dans le prochain chapitre, nous verrons une méthode plus "standard" pour obtenir le même résultat, ne vous inquiétez pas : vous n'êtes pas condamné à utiliser IFNULL qui en fait n'est que très rarement utilisé et assez peu pratique... ^^

Le système de classement en une seule requête !

Vous vous souvenez du système de classement vu dans le chapitre précédent ? (j'espère que oui sinon mon enseignement ne serait pas d'une grande utilité :D ). Voici les requêtes que je vous avais données :

Code : SQL
1
2
SET @place = 0;
SELECT @place := @place + 1 AS place, pseudo, points FROM joueurs ORDER BY points DESC;


Et bien grâce aux fonctions que nous venons de voir, nous pouvons maintenant tout rassembler sur une seule ligne !

En fait, ça ne sert à strictement rien et ça ralentit un peu la requête, mais c'est toujours intéressant de le savoir car peut-être que vous serez confrontés à des cas où vous serez obligés d'utiliser la technique suivante :

Code : SQL
1
SELECT @place := COALESCE(@place, @place := 0) + 1 AS place, pseudo, points FROM joueurs ORDER BY points DESC;

Image utilisateur


Pratique non ? On peut également vérifier facilement si une variable a déjà été déclarée grâce à la fonction IFNULL. Comme vous le constatez, les fonctions de traitement des valeurs NULL sont relativement pratiques couplées aux variables utilisateur. Elles permettent aussi de compacter les requêtes et d'éviter un CASE (on verra ça dans le prochain chapitre) ou un IF (prochain chapitre également :p ), bien que parfois, ces fonctions (particulièrement IFNULL) font tout sauf compacter la requête. :D :p

Q.C.M.

Une requête de cette sorte est-elle permise ?
Code : SQL
1
SELECT [...] WHERE champ = NULL;
Que renvoie la fonction COALESCE ?
Que renvoie la requête suivante ?

Code : SQL
1
SELECT IFNULL(NULL, 'bonjour');


Voilà, j'espère que ça vous a plu et que vous vous rendez compte de l'erreur que font les développeurs qui préfèrent travailler avec des chaînes vides plutôt qu'avec des valeurs nulles puis qui doivent se farcir des IF au lieu d'un simple COALESCE ou IFNULL. :D
Chapitre précédent Sommaire Chapitre suivant
Auteur : Shepard
Noter et commenter ce tutoriel
Imprimer ce tutoriel

Nombre de connectés 242 Zér0s connectés | Requêtes SQL 10 requêtes | Temps de génération de la page 0.0496s (0.0327s)

Changer de design - Revue de presse - En savoir plus - Plan du site
Nous contacter - Mentions légales - Publicité
Politique d'accessibilité - Fil RSS - XHTML 1.0 - CSS 2.0

Y'a plus rien à lire, faut remonter maintenant !