How to select sum -or- 0 if no records exist?

前端 未结 4 951
闹比i
闹比i 2020-12-09 14:48

I need to write a query that returns the sum of all values that meet a certain criteria, but the query needs to return 0 if no rows are found, rather than null. For example

4条回答
  •  挽巷
    挽巷 (楼主)
    2020-12-09 15:23

    To do this properly, you may want to distinguish between the case where there are actual NULL results in the data you're summing, and the case where there are no values at all to sum.

    Suppose we have the following:

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

    We would like empty sums to be zero, but sums involving NULL to be NULL. One (rather torturous) way to do that is:

    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)
    

    Perhaps there's a better way I haven't thought of.

    Unfortunately, the SQL standard defines SUM to be null when no elements are summed, and MySQL has no choice but to follow that standard.

提交回复
热议问题