2012-01-17 44 views
18

我需要编写一个查询返回所有满足特定条件的值的总和,但如果没有找到行,查询需要返回0而不是null。例如:如何选择总和 - 或 - 0如果没有记录存在?

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

有人可以解释,如果这是可能的?

回答

44

如何:

SELECT COALESCE(sum(num), 0) AS val FROM tab WHERE descr LIKE "%greetings%"; 

COALESCE功能基本上说“返回的第一个参数,除非它是空在这种情况下返回第二个参数” - 这是在这些情况下,会非常方便。

+0

这实际上并没有达到预期效果 - 这也会掩盖作为'num'值本身一部分的'NULL'。 – 2017-11-11 04:46:53

+0

它的工作原理,很好的解决方案 – nitin 2017-11-18 07:01:04

1

这工作:

SELECT IF(SUM(num) IS NULL, 0, SUM(num)) AS val FROM tab WHERE descr LIKE "%whatever%"; 

IF()有三个参数:(1)声明,(2)的值,以适用,如果声明是真实的,和(3)的值;如果申请声明是错误的。

8

检查MySQL documentation for IFNULL

SELECT SUM(IFNULL(num, 0)) as val FROM tab WHERE descr LIKE "%greetings%"; 

当然,这里假设你的num场可为空并且没有缺省值。另一个可能的解决方案是为num字段设置缺省值0,这将解决您遇到的问题。

+6

IFNULL应该在SUM之外,否则如果找不到行,它将返回null。 – 2012-11-30 15:31:41

0

要正确地做到这一点,您可能需要区分在您正在求和的数据中实际存在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别无选择,只能遵循该标准。

相关问题