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

为何将WHERE子句条件移至JOIN子句会导致SQL Server查询结果不同?

两个左连接查询结果不同的原因解析

核心差异:过滤条件的位置(ON子句 vs WHERE子句)

这两个查询的本质区别在于ff.sendtime < '2023-01-21'条件的放置位置,直接改变了左连接的执行逻辑和最终统计范围:

  1. 第一个查询的执行逻辑
select count(*)
from ff
         left join d on
    ff.ID = d.id
where ff.sendtime < '2023-01-21' and d.id is null
  • 第一步:执行全量左连接——将ff表的所有记录(无论sendtime取值)按ID与d表关联,关联失败的记录会保留d表字段为NULL。
  • 第二步:执行WHERE过滤——仅保留ff.sendtime < '2023-01-21'且未匹配到d表的记录。
  • 最终统计:ff表中sendtime早于2023-01-21且在d表无匹配ID的记录数。
  1. 第二个查询的执行逻辑
select count(*)
from ff
         left join d on
    ff.sendtime < '2023-01-21' and ff.ID = d.id
where d.id is null
  • 第一步:执行带条件的左连接——仅当ff.sendtime < '2023-01-21'且ff.ID = d.id时,才会尝试关联d表;对于ff.sendtime >= '2023-01-21'的记录,因不满足ON子句条件,不会与d表关联,直接保留且d表字段为NULL。
  • 第二步:执行WHERE过滤——保留所有d.id is null的记录,包含两类:
    • ff表中sendtime早于2023-01-21但未匹配到d表的记录;
    • ff表中sendtime >= 2023-01-21的所有记录(这类记录未参与关联,d.id自然为NULL)。
  • 最终统计:ff表中sendtime >= 2023-01-21的所有记录 + sendtime早于2023-01-21且在d表无匹配ID的记录。

等价写法调整

若要让第二个查询与第一个返回相同结果,需将ff.sendtime < '2023-01-21'移至WHERE子句(即第一个查询的写法),或在ON子句外补充过滤条件:

select count(*)
from ff
         left join d on ff.ID = d.id
where ff.sendtime < '2023-01-21' and d.id is null

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 10:43:14