当前位置: 首页 > news >正文

写联表查询SQL时筛选条件写在where 前面和后面有啥区别

写联表查询SQL时筛选条件写在where 前面和后面有啥区别

ON 条件作用于「表连接阶段」,WHERE 条件作用于「连接完成后的结果集过滤阶段」,二者在逻辑执行顺序、对连接结果的影响上完全不同

一、先明确你的 SQL 中「条件的当前位置」

你的 SQL 里存在两类筛选条件,先对应到「ON 前 / 后」的概念:

 

条件位置具体条件作用阶段
JOIN 的 ON 子句中rel.id = ord.bidding_indicator_release_id(连接条件)、ord.del_flag = 'N'cate.review_status != 'shbh'表连接阶段
WHERE 子句中rel.del_flag = 'N'rel.release_status = 'yjcj'连接后结果集过滤

 

下面通过「把 ON 中的条件移到 WHERE 后」和「把 WHERE 中的条件移到 ON 中」的对比,说明核心差异。

二、核心区别:作用阶段与对连接结果的影响

1. 对「左连接(LEFT JOIN)」的影响(最关键!)

你的 SQL 用了 LEFT JOIN(左表是 bidding_indicator_release_info rel,右表是 ord 和 cate)。左连接的核心规则是:左表的所有记录都会保留,右表只保留满足 ON 条件的记录;右表不满足条件的记录,字段值会填充为 NULL

 

这时候,「条件写在 ON 还是 WHERE」会直接决定右表记录是否保留,甚至影响左表记录的最终结果:

案例 1:ord.del_flag = 'N' 写在 ON 中 vs 写在 WHERE 中
  • 写在 ON 中(当前写法)
    左连接时,只匹配 ord 表中 del_flag = 'N' 的记录。如果 rel 表某条记录没有对应的 ord 记录(或 ord 记录 del_flag = 'Y'),ord 相关字段(如 user_idprice)会填充为 NULL,但 rel 表的这条记录会保留

  • 移到 WHERE 中
    左连接先保留 rel 的所有记录(包括没有对应 ord 的记录),连接完成后,再用 WHERE ord.del_flag = 'N' 过滤结果集。
    但此时,rel 表中没有对应 ord 的记录,ord.del_flag 是 NULL,而 NULL = 'N' 不成立,所以 这些 rel 记录会被过滤掉,最终效果等同于「内连接(INNER JOIN)」,左表的 “左连接特性” 失效。

案例 2:cate.review_status != 'shbh' 写在 ON 中 vs 写在 WHERE 中

同理,cate 是通过 LEFT JOIN 关联到 ord 的:

  • 写在 ON 中
    只匹配 cate 表中 review_status != 'shbh' 的记录。如果 ord 没有对应 cate 记录(或 cate 的 review_status = 'shbh'),cate 相关字段(ship_info_idship_name)会填充为 NULL,但 rel 和 ord 的记录会保留。

  • 移到 WHERE 中
    连接完成后过滤 cate.review_status != 'shbh',此时 cate 字段为 NULL 的记录(无对应 cate 或 review_status = 'shbh')会被过滤,导致 rel 和 ord 的记录也被删除,破坏左连接逻辑。

2. 对「内连接(INNER JOIN)」的影响(差异较小)

如果你的 SQL 是 INNER JOIN(只保留左右表都匹配的记录),那么「条件写在 ON 还是 WHERE」最终结果可能相同,但逻辑执行顺序不同

 

  • ON 条件:先过滤右表,再和左表做内连接(减少连接的数据量,效率可能更高);
  • WHERE 条件:先做内连接(保留所有匹配记录),再过滤结果集(连接的数据量更大,效率可能更低)。

 

但你的 SQL 是 LEFT JOIN,所以内连接的场景不适用,核心差异还是集中在左连接的记录保留逻辑上。

3. 对「左表(rel)的过滤条件」的影响

你的 WHERE 中有 rel.del_flag = 'N' 和 rel.release_status = 'yjcj',这些是对左表 rel 的过滤条件。如果把它们移到 LEFT JOIN rel ON ... 中(假设 rel 是其他表的右表,但你的 SQL 中 rel 是主表,没有左表):

 

  • 若 rel 是主表(FROM 后的表),过滤条件只能写在 WHERE 中(因为主表没有 ON 条件);
  • 若 rel 是被连接的右表(如 A LEFT JOIN rel ON ...),则 rel.del_flag = 'N' 写在 ON 中,会保留 A 表所有记录,只匹配 rel 满足条件的记录;写在 WHERE 中,会过滤掉 A 表中没有匹配 rel 或 rel 不满足条件的记录,等同于内连接。

三、总结:你的 SQL 中条件位置的「正确与否」

结合业务需求(通常左连接是为了保留主表 rel 的所有有效记录,同时关联右表的匹配数据),你的 SQL 中条件位置大部分合理,但有一个细节需要注意:

 

条件当前位置是否合理?
rel.id = ord.idON合理:连接条件必须写在 ON 中,否则无法关联两表。
ord.del_flag = 'N'ON合理:保留 rel 所有有效记录,只关联 ord 未删除的记录(无效 ord 显示 NULL)。
cate.review_status!='shbh'ON合理:保留 ord 记录,只关联 cate 未被驳回的记录(无效 cate 显示 NULL)。
rel.del_flag = 'N'WHERE合理:过滤主表 rel 未删除的记录(主表过滤只能写在 WHERE)。
rel.release_status='yjcj'WHERE合理:过滤主表 rel 已竞价成交的记录(主表过滤只能写在 WHERE)。

四、关键口诀

判断条件写在 ON 还是 WHERE,记住这 2 条:

  1. 连接条件(如 A.id = B.a_id)必须写在 ON 中,否则无法建立表关联;
  2. 左连接中,想保留左表所有记录 → 右表的过滤条件写在 ON 中;想过滤掉左表中无右表匹配的记录 → 右表的过滤条件写在 WHERE 中(等同于内连接);
  3. 主表(FROM 后的表)的过滤条件,只能写在 WHERE 中(主表没有 ON 条件,写在 ON 中无效)。
http://www.dtcms.com/a/389668.html

相关文章:

  • ARM(13) - PWM控制LCD
  • Python基础 3》流程控制语句
  • 牛客算法基础noob44——数组计数维护
  • 并发编程原理与实战(三十)原子操作进阶,原子数组与字段更新器精讲
  • 前端-详解Vue异步更新
  • 基于风格的对抗生成网络
  • 【JavaScript】SSE
  • JAVA算法练习题day15
  • 线性表---双链表概述及应用
  • 作业帮前端面试(准备)
  • 51单片机-使用单总线通信协议驱动DS18B20模块教程
  • 全文单侧引号的替换方式
  • NVIDIA RTX4090 在Ubuntu系统中开启P2P peer access 直连访问
  • 再次深入学习深度学习|花书笔记2
  • 中移物联ML307C模组OPENCPU笔记1
  • 计算机视觉
  • VScode实现uniapp小程序开发(含小程序运行、热重载等)
  • Redis的各种key问题
  • 元宇宙与医疗产业:数字孪生赋能医疗全链路革新
  • 为你的数据选择合适的分布:8个实用的概率分布应用场景和选择指南
  • 掌握Stable Diffusion WebUI:模型选择、扩展管理与部署优化
  • LVGL拼音输入法优化(无bug)
  • 多层感知机:从感知机到深度学习的关键一步
  • PostgreSQL绿色版整合PostGIS插件,以Windows 64位系统为例
  • GEO优化推荐案例:2025年上海源易信息科技的全链路实践
  • 时空预测论文分享:多模态融合 空间索引结构 超图 时演化因果关系
  • 智能手机产量增长4%
  • MySQL高可用MHA实战指南
  • Coze源码分析-资源库-创建工作流-后端源码-核心技术/总结
  • 《棒球团建》国家级运动健将·棒球1号位