我需要编写一个返回满足特定条件的所有值的总和的查询,但如果没有找到行,则查询需要返回0,而不是null。例如:
tab
+---------------+-----+
| descr | num |
+---------------+-----+
| hello there | 5 |
| hi there | 10 |
| hello | 10 |
| hi there! | 15 |
+---------------+-----+
此查询:
SELECT sum(num) AS val FROM tab WHERE descr LIKE "%hello%";
应该而且确实会返回15
。但是:
SELECT sum(num) AS val FROM tab WHERE descr LIKE "%greetings%";
应该返回0
,但会返回null
。
有人可以解释这是否可行?
答案 0 :(得分:66)
怎么样:
SELECT COALESCE(sum(num), 0) AS val FROM tab WHERE descr LIKE "%greetings%";
COALESCE函数基本上表示“返回第一个参数,除非它返回null,在这种情况下返回第二个参数” - 在这些情况下它非常方便。
答案 1 :(得分:9)
检查MySQL documentation for IFNULL。
SELECT SUM(IFNULL(num, 0)) as val FROM tab WHERE descr LIKE "%greetings%";
当然,这假设您的num
字段可以为空并且没有默认值。另一种可能的解决方案是为num字段设置默认值0
,这可以解决您遇到的问题。
答案 2 :(得分:3)
为了正确地执行此操作,您可能希望区分在您要求求和的数据中存在实际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标准defines SUM
to be null when no elements are summed和MySQL别无选择,只能遵循该标准。
答案 3 :(得分:1)
这有效:
SELECT IF(SUM(num) IS NULL, 0, SUM(num)) AS val FROM tab WHERE descr LIKE "%whatever%";
IF()接受三个参数:(1)语句,(2)语句为真时应用的值,(3)语句为假时应用的值。