web-dev-qa-db-ja.com

合計を選択する方法-または-レコードが存在しない場合は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を返します。

これが可能かどうか誰かが説明できますか?

30
ewok

どうですか:

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

[〜#〜] coalesce [〜#〜] 関数は基本的に「最初のパラメーターを返します。nullでない限り、2番目のパラメーターを返します」-これらのシナリオでは非常に便利です。

67

IFNULLのMySQLドキュメント を確認してください。

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

もちろん、これはnumフィールドがnull可能であり、デフォルト値がないことを前提としています。別の可能な解決策は、numフィールドに0のデフォルトを設定することです。これにより、発生している問題を解決できます。

9
sesser

これを適切に行うには、合計するデータに実際の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標準 要素が合計されない場合はSUMをnullに定義します であり、MySQLにはその標準に従う以外に選択肢がありません。

3
Ken Williams

これは動作します:

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

IF()は次の3つのパラメーターを取ります。(1)ステートメント、(2)ステートメントがtrueの場合に適用する値、(3)ステートメントがfalseの場合に適用する値。

1
Thomas Kelley