You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何筛选所有状态均为NOK的服务(排除含OK状态的服务)

筛选所有状态均为NOK的服务

问题背景

现有一张包含服务名称(Service)和服务状态(state)的表,同一服务会部署在多台主机上,状态可能存在差异。需要筛选出所有行状态都是NOK的服务——只要服务存在任意一行OK状态,就排除该服务。

示例源数据

Servicestate
ServiceAOK
ServiceBNOK
ServiceANOK
ServiceBNOK

期望结果

仅返回ServiceB,因为它的所有行状态均为NOK,而ServiceA存在OK状态的行。

现有尝试的问题

你之前用分组统计的SQL:

WITH a AS (
    SELECT service, state, count(*)
    FROM table
    GROUP BY service, state
)
SELECT * FROM a;

得到的是按service+state组合的计数,但这种分组方式无法直接判断某个服务是否存在非NOK状态。如果用WHERE state != 'NOK',只会过滤掉单条OK行,但ServiceA的NOK行依然会被保留,导致结果错误。

解决方案

以下是几种高效的实现方式:

方法1:GROUP BY + HAVING 过滤(推荐,适用于状态只有OK/NOK的场景)

通过分组后检查服务的状态范围,确保所有状态都是NOK:

SELECT service
FROM your_table
GROUP BY service
HAVING MIN(state) = 'NOK' AND MAX(state) = 'NOK';

如果状态不止OK/NOK两种,用更通用的统计方式:

SELECT service
FROM your_table
GROUP BY service
HAVING SUM(CASE WHEN state != 'NOK' THEN 1 ELSE 0 END) = 0;

原理:统计每个服务下非NOK状态的行数,只有当这个计数为0时,说明该服务所有行都是NOK。

方法2:NOT EXISTS 子查询

直接排除存在非NOK状态的服务:

SELECT DISTINCT service
FROM your_table t_main
WHERE NOT EXISTS (
    SELECT 1
    FROM your_table t_sub
    WHERE t_sub.service = t_main.service
      AND t_sub.state != 'NOK'
);

原理:找到所有不存在非NOK状态行的服务,DISTINCT用来去除同一服务的重复行。

方法3:窗口函数标记

用窗口函数给每个服务计算非NOK行数,再筛选:

WITH service_status AS (
    SELECT 
        service,
        SUM(CASE WHEN state != 'NOK' THEN 1 ELSE 0 END) OVER (PARTITION BY service) AS non_nok_total
    FROM your_table
)
SELECT DISTINCT service
FROM service_status
WHERE non_nok_total = 0;

原理:窗口函数按服务分组统计非NOK的总行数,筛选出计数为0的服务即可。

内容的提问来源于stack exchange,提问作者Nicolas Greder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 21:50:36