提问者:小点点

如何对过去7天的每一个非空条目进行求和?


在LAMP堆栈上使用PHP,PDO和MySQL8。 使用Adminer测试查询。

我有一个这样的数据库:

+------------+----------------+------+--------+--------+--------+
| DATE       | CLIENT         |AM1200| AM1230 | AM0100 | AM0130 | ...... (etc, for every 30 mins in a 24 hour day)
+------------+----------------+------+--------+--------+--------+
| 2020-06-20 | tx1.server.com | ER13 | NULL   | NULL   | OK     | ......
| 2020-06-20 | tx2.server.com | OK   | NULL   | NULL   | NULL   | ......
| 2020-06-20 | tx3.server.com | OK   | OK     | OK     | OK     | ......
| 2020-06-20 | tx4.server.com | OK   | OK     | OK     | OK     | ......
| 2020-06-20 | tx5.server.com | UNK  | UNK    | NULL   | NULL   | ......
| 2020-06-21 | tx1.server.com | OK   | OK     | OK     | UNK    |  ......
| 2020-06-21 | tx2.server.com | NULL | NULL   | NULL   | NULL   | ......
| 2020-06-21 | tx3.server.com | OK   | OK     | OK     | OK     | ......
| 2020-06-21 | tx4.server.com | OK   | OK     | OK     | OK     | ......
| 2020-06-21 | tx5.server.com | NULL | NULL   | OK     | OK     | ......

我需要统计过去7天每个“客户端”的非空值的总数。 最终结果应该是这样的:

+----------------+----------------+
| CLIENT         | TOTAL NON-NULL |
+----------------+----------------+
| tx3.server.com | 336            |
| tx4.server.com | 328            |
| tx1.server.com | 281            |
| tx5.server.com | 269            |
| tx2.server.com | 42             |

我是MySQL的新手,我已经尝试了在SO和MySQL开发文档上找到的20多个不同的解决方案,但是我无法达到我想要的结果。

我的大多数尝试都得到了所有字段的计数,无论它们是否为空。

我认为这个(略微简短的)询问是我迄今为止最接近的尝试。 但对我来说还是不太好用。 它给我所有字段的计数(空或不)。

SELECT client, 
        SUM(IF(am1200=NULL,NULL,1) + IF(am1230=NULL,NULL,1) + IF(am0100=NULL,NULL,1) +  ....etc) AS Total
FROM `client_pings`
WHERE date >= `2020-06-15`
AND date <= `2020-06-23`
GROUP BY client
ORDER BY Total DESC
LIMIT 20

共1个答案

匿名用户

简化版本的数据,假设为空值,并使用is null测试空值

drop table if exists t;
create table t
(id int, am1 varchar(10),am2 varchar(10),am3 varchar(10));
insert into t values
(1,null,'maybe','nok'),
(2,'ok','maybe','nok')
;

select id,
         sum(if(am1 is null,0,1)+if(am2 is null,0,1)+if(am3 is null,0,1)) total
from t
group by id
order by total desc;

+------+-------+
| id   | total |
+------+-------+
|    2 |     3 |
|    1 |     2 |
+------+-------+
2 rows in set (0.001 sec)