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

求助:如何编写SQL查询无关联有效c记录的s表记录

求助:如何编写SQL查询无关联有效c记录的s表记录

首先得帮你梳理下需求的核心:我们要找的是所有不存在“活跃中间表记录关联到活跃c记录”的s,也就是三种情况:

  1. s完全没有关联任何cs记录
  2. s关联的cs都是已删除的(cs.del=1)
  3. s关联的活跃cs(cs.del=0)对应的c要么不存在,要么是已删除的(c.del=1)

先说说你原来查询的问题:你的SQL逻辑完全搞反了——你当前的WHERE条件是在筛选「有活跃cs/无cs,且有活跃c/无c」的记录,最后还要count>0,这其实是在找那些有有效关联的s,和你要的「无有效关联」正好相反,所以自然查不到正确结果。

下面给你两种最直观的正确写法,都能完美匹配你的需求:


方法一:用NOT EXISTS(逻辑最清晰,推荐)

这种写法直接对应需求的“不存在有效关联”的语义,非常容易理解:

SELECT s.id
FROM s
WHERE NOT EXISTS (
    -- 子查询:检查当前s是否存在「活跃cs关联到活跃c」的记录
    SELECT 1
    FROM cs
    INNER JOIN c ON cs.c_id = c.id
    WHERE cs.s_id = s.id
      AND cs.del = 0  -- 只看活跃的中间表记录
      AND c.del = 0   -- 只看活跃的c记录
)

逻辑验证(对应你的例子):

  • s.id=1:子查询能找到cs.s_id=1, cs.c_id=$, c.del=0这条符合条件的记录,所以NOT EXISTS不成立,不会被选中
  • s.id=2:子查询找不到任何cs记录,NOT EXISTS成立,会被选中
  • s.id=3:所有活跃cs对应的c都是已删除的(c.del=1),子查询找不到符合条件的记录,NOT EXISTS成立,会被选中

方法二:用LEFT JOIN + GROUP BY

如果你更习惯用连接的方式写,也可以用左连接筛选活跃关系,再通过分组计数判断:

SELECT s.id
FROM s
-- 左连接「活跃的cs记录」
LEFT JOIN cs ON s.id = cs.s_id AND cs.del = 0
-- 再左连接「活跃的c记录」(只关联和活跃cs匹配的c)
LEFT JOIN c ON cs.c_id = c.id AND c.del = 0
GROUP BY s.id
-- 分组后,如果活跃c的计数为0,说明没有有效关联
HAVING COUNT(c.id) = 0

逻辑验证:

  • s.id=1:会关联到一条活跃cs+活跃c的记录,COUNT(c.id)=1,不满足=0,不会被选中
  • s.id=2:没有任何cs关联,c.id全为null,COUNT(c.id)=0,会被选中
  • s.id=3:活跃cs对应的c都是已删除的,所以左连接c后c.id全为null,COUNT(c.id)=0,会被选中

为什么你的原查询不行?

再回头看你的SQL:

SELECT s.id FROM s 
LEFT JOIN cs on s.id = cs.s_id 
LEFT JOIN c on c.id = cs.c_id 
WHERE (cs.del = 0 OR cs.del IS NULL) AND (c.del = 0 OR c.del IS NULL) 
GROUP BY s.id 
HAVING COUNT(s.id) > 0

这里的问题:

  1. WHERE条件逻辑错误:你筛选的是「活跃cs/无cs」且「活跃c/无c」的记录,这其实是在找有有效关联的s,和需求完全相反
  2. HAVING条件错误:COUNT(s.id)永远不会为0(因为s是主表,每条s至少有一条记录),这个条件完全起不到筛选作用

用上面推荐的两种写法,就能完美解决你的问题啦!

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 09:34:34