【问题标题】:MySQL: How to count rows (on different conditions) on a filtered data set?MySQL:如何计算过滤数据集上的行数(在不同条件下)?
【发布时间】:2018-01-25 12:06:00
【问题描述】:

由于我对 MySQL 的了解有限我无法找到合适的语法来满足我想在 MySQL 中获得的内容(MariaDB 10.0;无法将其升级到更新的版本):

  1. 上传最近 24 小时的数据(本例中:CPU_load;实际 生活它可能是一个计算重过滤,而不是像这个例子中的一个简单的last 24h);

  2. 统计过滤后满足不同条件的值。

单个查询“过去 24 小时内有多少值高于 95%?”很简单:

SELECT COUNT(*)
FROM (
    SELECT *
    FROM `server-statistics` 
    WHERE `Date_Time` >= DATE_SUB(UTC_TIMESTAMP(), INTERVAL 1 DAY) 
) as H24
WHERE CPU_load > 95

为了解释起见,我留下了 H24 的(这里没用的)定义。

问题

如果我要依靠多个条件(即:>过去 24 小时内的 90%、过去 24 小时内 >95%、过去 24 小时内 >98% 等)与前一个查询类似,过滤后的组 H24 会一遍又一遍地重新计算。

如果它在调用之间被缓存,这不是一个真正的问题,但我更愿意一次计算多个条件下的行数。

在伪 SQL 中应该是这样的:

SELECT COUNT(*) WHERE CPU_load > 90,
       COUNT(*) WHERE CPU_load > 95,
       COUNT(*) WHERE CPU_load > 98
FROM `server-statistics` 
WHERE `Date_Time` >= DATE_SUB(UTC_TIMESTAMP(), INTERVAL 1 DAY) 

在纯 MySQL 中可以吗?

【问题讨论】:

  • 一个值是否应该算在98%以上以及95%以上和90%以上?
  • 在现实生活中,是的,但我试图理解语法这并不重要。与此同时,Susang 已经为我提供了一个工作示例。还是谢谢你。

标签: mysql group-by count


【解决方案1】:

您可以使用CASE 进行条件计数,如下所示

SELECT SUM(CASE WHEN CPU_load BETWEEN 90 AND 94 THEN 1 ELSE 0 END) AS A1,
       SUM(CASE WHEN CPU_load BETWEEN 95 AND 97 THEN 1 ELSE 0 END) AS A2,
       SUM(CASE WHEN CPU_load > 98 THEN 1 ELSE 0 END) AS A3
FROM `server-statistics` 
WHERE `Date_Time` >= DATE_SUB(UTC_TIMESTAMP(), INTERVAL 1 DAY)

计算范围内的数据似乎更有意义,但如果您仍想保持状态,请改用以下:

SUM(CASE WHEN CPU_load > 90 THEN 1 ELSE 0 END) AS A1
SUM(CASE WHEN CPU_load > 95 THEN 1 ELSE 0 END) AS A2
SUM(CASE WHEN CPU_load > 98 THEN 1 ELSE 0 END) AS A3

将十进制值寻址为 94.5

--Adjust the comparison value according to your requirement just provided the example.

SUM(CASE WHEN CPU_load > 90 AND CPU_load <= 95 THEN 1 ELSE 0 END) AS A1
SUM(CASE WHEN CPU_load > 95 AND CPU_load <= 98 THEN 1 ELSE 0 END) AS A2
SUM(CASE WHEN CPU_load > 98 THEN 1 ELSE 0 END) AS A3

【讨论】:

  • 如果按范围计算,可能会出现间隙和小数位数问题
  • 非常感谢@susang!作为一个小修复,我不得不将您示例的标签 (1, 2,3) 更改为有效的 (A1,A2,A3),否则它会抱怨语法错误。
  • @bw_üezi,我赞成您的评论,因为我认为您谈论的是 Null 值和空集。或者除此之外还有什么别的吗?
  • 例如值94.5 既不是between 90 and 94 也不是betwwen 95 and 97
  • 更新了地址十进制值。您可以根据自己的需要选择一个并调整比较值。
猜你喜欢
  • 1970-01-01
  • 2017-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-16
  • 1970-01-01
  • 1970-01-01
  • 2022-09-22
相关资源
最近更新 更多