Чтобы сделать это правильно, вы можете различить случай, когда есть действительные NULL
результаты в суммируемых вами данных, и случай, когда нет значений для суммирования.
Предположим, у нас есть следующее:
mysql> select * from t;
+----------+------+
| descr | num |
+----------+------+
| hiya | 5 |
| hi there | 10 |
| yo | NULL |
+----------+------+
Мы бы хотели, чтобы пустые суммы были равны нулю, но суммы с NULL
равны NULL
. Один (довольно мучительный) способ сделать это:
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)
Возможно, есть лучший способ, о котором я не думал.
К сожалению, стандарт SQL определяет SUM
как ноль, когда никакие элементы не суммируются , и у MySQL нет иного выбора, кроме как следовать этому стандарту.