如何合并两个SQL查询计算服务器繁忙状态占比?
合并SQL查询计算服务器繁忙占比
嗨,这事儿好办!其实不用分开跑两次查询,咱们可以一次性搞定统计和占比计算,或者把两个查询的结果合并起来计算,给你两种实用方案参考:
方案一:单查询直接统计+计算占比(效率更高)
这种方法只需要扫描一次数据表,性能更优。用CASE WHEN语句分别统计繁忙和非繁忙的数量,然后直接算出占比:
SELECT epoch as time_sec, COUNT(CASE WHEN bw > 0 THEN 1 END) as Used, COUNT(CASE WHEN bw = '0' THEN 1 END) as NotUsed, -- 计算繁忙占比,用NULLIF避免除数为0的错误 ROUND( COUNT(CASE WHEN bw > 0 THEN 1 END)::numeric / NULLIF(COUNT(1), 0), 2 ) as BusyRatio FROM tablename WHERE server in ($server) and interface in ($interface) GROUP BY epoch;
关键部分说明:
COUNT(CASE WHEN bw > 0 THEN 1 END):只统计bw>0的有效记录,不满足条件的会被视为NULL,COUNT不会统计NULL值NULLIF(COUNT(1), 0):防止总记录数为0时出现除以0的报错,此时占比会返回NULLROUND(..., 2):把占比保留两位小数,你可以根据需求调整小数位数- 只扫描一次表,比两次查询再合并的效率高很多,优先推荐这个方案
方案二:合并原有两个查询的结果
如果你更习惯保留原来的两个查询结构,可以用FULL JOIN把结果合并后再计算占比:
WITH BusyData AS ( SELECT epoch as time_sec, count(1) as Used FROM tablename WHERE server in ($server) and bw > 0 and interface in ($interface) GROUP BY epoch ), NotBusyData AS ( SELECT epoch as time_sec, count(1) as NotUsed FROM tablename WHERE server in ($server) and bw = '0' and interface in ($interface) GROUP BY epoch ) SELECT COALESCE(b.time_sec, nb.time_sec) as time_sec, COALESCE(b.Used, 0) as Used, COALESCE(nb.NotUsed, 0) as NotUsed, ROUND( COALESCE(b.Used, 0)::numeric / NULLIF(COALESCE(b.Used, 0) + COALESCE(nb.NotUsed, 0), 0), 2 ) as BusyRatio FROM BusyData b FULL JOIN NotBusyData nb ON b.time_sec = nb.time_sec;
关键部分说明:
WITH子句用来定义两个临时数据集,就是你原来的两个查询结果FULL JOIN确保即使其中一个查询在某个时间点没有数据,也能保留该时间点的记录COALESCE(..., 0):把NULL值转换成0,避免计算时出现NULL结果- 同样用
NULLIF处理除数为0的情况
两种方案都能帮你得到包含时间、Used、NotUsed和繁忙占比的完整结果!
内容的提问来源于stack exchange,提问作者Svan
相关产品推荐
相关产品推荐

