2012-01-17 15 views
18

特定の基準を満たすすべての値の合計を返すクエリを作成する必要がありますが、nullではなく行が見つからない場合はクエリで0を返す必要があります。合計を選択する方法 - または - レコードが存在しない場合は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

方法について:

COALESCE機能は基本的に「それがその場合は、二番目のパラメータを返すヌルでない限り、最初のパラメータを返す」と言う
SELECT COALESCE(sum(num), 0) AS val FROM tab WHERE descr LIKE "%greetings%"; 

- それは、これらのシナリオでは非常に便利です。

+0

これは実際には望ましい効果がありません。これは、 'num'値そのものの一部である' NULL'もマスクします。 –

+0

それはうまくいっています。 – nitin

1

これは動作します:

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

()は3つのパラメータを取る場合:文が真である場合(1)文は、(2)の値を適用するために、および(3)の値があれば適用します文は偽です。

8

MySQL documentation for IFNULLを確認してください。もちろん

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

、これはあなたのnumフィールドがNULL可能であると仮定し、デフォルト値はありません。考えられる問題を解決するnumフィールドにデフォルトの0を設定することもできます。

+6

IFNULLはSUMの外にある必要があります。そうでなければ、行が見つからなければnullを返します。 –

0

これを正しく実行するには、加算するデータに実際にNULLの結果がある場合と、合計する値がまったくない場合を区別したい場合があります。

は、我々は次があるとします。

mysql> select * from t; 
+----------+------+ 
| descr | num | 
+----------+------+ 
| hiya  | 5 | 
| hi there | 10 | 
| yo  | NULL | 
+----------+------+ 

我々はゼロであると、空の合計をしたいと思いますが、NULLを含む合計がNULLします。それを行う1つの(むしろ拷問)の方法は次のとおりです。

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は、その標準に従うこと以外に選択肢はありません。

関連する問題