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

MySQL两SELECT子查询使用!=连接未返回预期空结果原因

问题原因

你当前的写法用了逗号分隔的隐式交叉连接(笛卡尔积),会先生成两个子查询结果的笛卡尔积,再做条件过滤,和你预期的逻辑完全不符:

  • 你的两个子查询各返回2条数据,交叉后会生成2*2=4条匹配记录:
    1. 前期学生1196 匹配 当日学生1196
    2. 前期学生1196 匹配 当日学生1861
    3. 前期学生1861 匹配 当日学生1196
    4. 前期学生1861 匹配 当日学生1861
  • 你写的prev_student.student_id != today_student.student_id条件,只会过滤掉上面4条里id完全相等的2条记录,剩下的2条交叉结果会正常返回,根本不是你要的「当日缴费的学生,在前期时间段完全没有缴费记录」的判断逻辑。

你需要的是反连接逻辑:筛选出当日学生集合中,学生ID完全不存在于前期学生集合的记录,而不是逐行交叉后判断单行ID不相等。

修正方案

两种常用写法都能实现你的需求,按当前测试数据都会返回空结果集:

方案1:NOT IN 实现

SELECT today_student.* 
FROM (
    SELECT scd.student_id, sc.transaction_date
    FROM student_collection_details scd
    INNER JOIN student_collection sc
     ON scd.student_collection_id = sc.id
    WHERE sc.transaction_date = DATE('2022-06-28 00:00:00')
    AND scd.admission_year_id = 2
    AND scd.month_id = 21
    AND scd.collection_head_id = 9  
    GROUP BY scd.student_id
) today_student
WHERE today_student.student_id NOT IN (
    SELECT scd.student_id
    FROM student_collection_details scd
    INNER JOIN student_collection sc
     ON scd.student_collection_id = sc.id
    WHERE sc.transaction_date BETWEEN DATE('2022-06-01 00:00:00') AND DATE('2022-06-27 00:00:00')
    AND scd.admission_year_id = 2
    AND scd.month_id = 21
    AND scd.collection_head_id = 9  
    GROUP BY scd.student_id
);

方案2:LEFT JOIN 反连接实现

SELECT today_student.* 
FROM (
    SELECT scd.student_id, sc.transaction_date
    FROM student_collection_details scd
    INNER JOIN student_collection sc
     ON scd.student_collection_id = sc.id
    WHERE sc.transaction_date = DATE('2022-06-28 00:00:00')
    AND scd.admission_year_id = 2
    AND scd.month_id = 21
    AND scd.collection_head_id = 9  
    GROUP BY scd.student_id
) today_student
LEFT JOIN (
    SELECT scd.student_id
    FROM student_collection_details scd
    INNER JOIN student_collection sc
     ON scd.student_collection_id = sc.id
    WHERE sc.transaction_date BETWEEN DATE('2022-06-01 00:00:00') AND DATE('2022-06-27 00:00:00')
    AND scd.admission_year_id = 2
    AND scd.month_id = 21
    AND scd.collection_head_id = 9  
    GROUP BY scd.student_id
) prev_student ON today_student.student_id = prev_student.student_id
WHERE prev_student.student_id IS NULL;

注:如果前期子查询的student_id可能存在NULL值,不要用NOT IN写法,会出现判断逻辑失效的问题,优先选LEFT JOIN反连接写法。

内容的提问来源于stack exchange,提问作者Sumon Bappi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 01:12:17