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

MySQL优化方案咨询:如何筛选所有服务均已删除的客户

筛选所有服务状态均为'DELETED'的客户最优实现方案

现有表结构

create table client (
    id INT NOT NULL,
    name varchar(100) NOT NULL,
    PRIMARY KEY ( id )
);

create table service (
    id INT NOT NULL,
    client_id INT NOT NULL,
    status varchar(36) NOT NULL,
    PRIMARY KEY ( id )
);

需求

筛选出所有服务状态**均为'DELETED'**的客户(默认包含无服务记录的客户,若需仅保留有服务的客户可调整方案)

当前尝试的问题

你当前的查询仅能返回client_id,无法获取客户的完整信息,且子查询逻辑可简化:

SELECT DISTINCT service.client_id
FROM service
WHERE service.id NOT IN (SELECT service.id FROM service s WHERE s.status <> 'DELETED' AND s.client_id = service.client_id); 

最优实现方案

方案1:LEFT JOIN排除法(高效易读)

直接关联client表,排除存在非'DELETED'服务的客户,同时包含无服务的客户:

SELECT c.id, c.name
FROM client c
LEFT JOIN service s ON c.id = s.client_id AND s.status <> 'DELETED'
WHERE s.id IS NULL;

逻辑:左连接匹配所有有非'DELETED'服务的客户,最终筛选出未匹配到的客户——这些客户要么没有服务,要么所有服务都是'DELETED'。

方案2:NOT EXISTS子查询(数据库优化友好)

多数数据库对NOT EXISTS的优化效果较好,逻辑直接清晰:

SELECT c.id, c.name
FROM client c
WHERE NOT EXISTS (
    SELECT 1 
    FROM service s 
    WHERE s.client_id = c.id 
    AND s.status <> 'DELETED'
);

逻辑:检查客户是否存在非'DELETED'的服务,不存在则符合条件。

方案3:分组统计验证(适用于需确认服务存在的场景)

如果要求客户至少有一个服务且所有服务都是'DELETED',可使用分组统计:

SELECT c.id, c.name
FROM client c
JOIN service s ON c.id = s.client_id
GROUP BY c.id, c.name
HAVING COUNT(CASE WHEN s.status <> 'DELETED' THEN 1 END) = 0;

逻辑:按客户分组后,统计非'DELETED'服务的数量,数量为0则所有服务均为'DELETED'。若要包含无服务的客户,将JOIN改为LEFT JOIN即可。

内容的提问来源于stack exchange,提问作者Sebastian Lore

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 09:35:11