MySQL(MariaDB10.0)如何在过滤数据集上多条件统计行数?
单条查询实现多条件统计的解决方案
当然可以实现!你需要利用MySQL/MariaDB的条件聚合特性,这样只需要扫描一次过滤后的数据集,就能完成所有统计需求,彻底避免重复计算的问题,而且MariaDB 10.0完全支持这种语法。
核心思路是:先用外层WHERE子句过滤出最近24小时的数据(不管你的过滤条件有多复杂,只需要在这里写一次),然后通过CASE WHEN配合聚合函数(SUM或COUNT)分别统计每个条件的行数。
具体实现代码
这里提供两种常用的写法,效果完全一致,你可以根据习惯选择:
写法1:用SUM配合CASE WHEN
SELECT SUM(CASE WHEN CPU_load > 90 THEN 1 ELSE 0 END) AS count_cpu_gt_90, SUM(CASE WHEN CPU_load > 95 THEN 1 ELSE 0 END) AS count_cpu_gt_95, SUM(CASE WHEN CPU_load > 98 THEN 1 ELSE 0 END) AS count_cpu_gt_98 FROM `server-statistics` WHERE `Date_Time` >= DATE_SUB(UTC_TIMESTAMP(), INTERVAL 1 DAY);
- 原理:满足条件时返回1,不满足返回0,
SUM会把所有1加起来,就是符合该条件的行数。
写法2:用COUNT配合CASE WHEN
SELECT COUNT(CASE WHEN CPU_load > 90 THEN 1 END) AS count_cpu_gt_90, COUNT(CASE WHEN CPU_load > 95 THEN 1 END) AS count_cpu_gt_95, COUNT(CASE WHEN CPU_load > 98 THEN 1 END) AS count_cpu_gt_98 FROM `server-statistics` WHERE `Date_Time` >= DATE_SUB(UTC_TIMESTAMP(), INTERVAL 1 DAY);
- 原理:
COUNT只会统计非NULL的值,当条件不满足时CASE默认返回NULL,因此只会统计符合条件的行。
为什么这比多次查询更好?
- 只需要扫描一次
server-statistics表(或者过滤后的结果集),避免了多次查询带来的重复计算,性能提升明显,尤其是当你的过滤条件很复杂时。 - 结果一次性返回所有统计值,不需要多次发起数据库请求。
不管你的实际过滤条件有多复杂(比如多表关联、复杂逻辑判断),只需要把所有过滤逻辑放在外层的WHERE子句里,所有聚合统计都会基于这个过滤后的数据集执行。
内容的提问来源于stack exchange,提问作者Alex Poca
相关产品推荐
相关产品推荐

