J'ai besoin d'écrire une requête qui renvoie la somme de toutes les valeurs qui répondent à certains critères, mais la requête doit retourner 0 si aucune ligne n'est trouvée, plutôt que null. Par exemple:
tab
+---------------+-----+
| descr | num |
+---------------+-----+
| hello there | 5 |
| hi there | 10 |
| hello | 10 |
| hi there! | 15 |
+---------------+-----+
Cette requête:
SELECT sum(num) AS val FROM tab WHERE descr LIKE "%hello%";
doit renvoyer 15
. Pourtant:
SELECT sum(num) AS val FROM tab WHERE descr LIKE "%greetings%";
devrait retourner 0
, mais renvoie null
.
Quelqu'un peut-il expliquer si cela est possible?
Que diriez-vous:
SELECT COALESCE(sum(num), 0) AS val FROM tab WHERE descr LIKE "%greetings%";
La fonction COALESCE dit essentiellement "retourne le premier paramètre, à moins qu'il ne soit nul auquel cas retourne le deuxième paramètre" - C'est assez pratique dans ces scénarios.
Vérifiez la documentation MySQL pour IFNULL .
SELECT SUM(IFNULL(num, 0)) as val FROM tab WHERE descr LIKE "%greetings%";
Bien sûr, cela suppose que votre champ num
est nullable et n'a pas de valeur par défaut. Une autre solution possible serait de définir une valeur par défaut de 0
pour le champ num qui devrait résoudre le problème que vous rencontrez.
Pour le faire correctement, vous souhaiterez peut-être faire la distinction entre le cas où il y a des résultats réels de NULL
dans les données que vous additionnez et le cas où il n'y a aucune valeur à additionner.
Supposons que nous ayons les éléments suivants:
mysql> select * from t;
+----------+------+
| descr | num |
+----------+------+
| hiya | 5 |
| hi there | 10 |
| yo | NULL |
+----------+------+
Nous aimerions que les sommes vides soient nulles, mais que les sommes impliquant NULL
soient NULL
. Une façon (plutôt tortueuse) de le faire est:
mysql> SELECT IF(has_null, NULL, total) AS sum FROM (
-> SELECT COALESCE(MAX(num IS NULL), 0) AS has_null, COALESCE(SUM(num), 0) AS total
-> FROM t WHERE num < 'ciao')
-> AS u;
+------+
| sum |
+------+
| 0 |
+------+
1 row in set, 1 warning (0.00 sec)
mysql> SELECT IF(has_null, NULL, total) AS sum FROM (
-> SELECT COALESCE(MAX(num IS NULL), 0) AS has_null, COALESCE(SUM(num), 0) AS total
-> FROM t)
-> AS u;
+------+
| sum |
+------+
| NULL |
+------+
1 row in set (0.00 sec)
mysql> SELECT IF(has_null, NULL, total) AS sum FROM (
-> SELECT COALESCE(MAX(num IS NULL), 0) AS has_null, COALESCE(SUM(num), 0) AS total
-> FROM t WHERE descr < 'namaste')
-> AS u;
+------+
| sum |
+------+
| 15 |
+------+
1 row in set (0.00 sec)
mysql> SELECT IF(has_null, NULL, total) AS sum FROM (
-> SELECT COALESCE(MAX(num IS NULL), 0) AS has_null, COALESCE(SUM(num), 0) AS total
-> FROM t WHERE descr > 'namaste')
-> AS u;
+------+
| sum |
+------+
| NULL |
+------+
1 row in set (0.00 sec)
Il y a peut-être une meilleure façon à laquelle je n'ai pas pensé.
Malheureusement, le standard SQL définit SUM
comme étant nul quand aucun élément n'est sommé , et MySQL n'a pas d'autre choix que de suivre ce standard.
Cela marche:
SELECT IF(SUM(num) IS NULL, 0, SUM(num)) AS val FROM tab WHERE descr LIKE "%whatever%";
IF () prend trois paramètres: (1) une déclaration, (2) la valeur à appliquer si la déclaration est vraie, et (3) la valeur à appliquer si la déclaration est fausse.