导读:本期聚焦于小伙伴创作的《SQL中如何实现非等值连接查询?在ON子句用范围判断或不等号的方法》,敬请观看详情。做报表时常碰到这类需求:把订单金额映射到对应的等级区间,或者找出比自己入职早的同事。这种没法用等于号关联两张表的情况,就是非等值连接。它和普通内连接的区别在于,ON后面不写列相等,而是写大于、小于、 BETWEEN 区间判断等条件。数据库会按笛卡尔积思路先展开再过滤,因此大表要小心性能。下文用员工表与薪资等级表、订单与汇率表两个场景,演示如何通过不等于号与范围条件写 JOIN,并说明索引怎么建才不至于让查询变慢。

在关系型数据库里,我们最熟悉的是通过主外键相等的“等值连接”,但业务里经常遇到按区间、按大小、按不等于来匹配两张表的情况,这就是非等值连接。它把连接条件从“列等于列”变成了“列大于列”“列 BETWEEN 低 AND 高”或者“列不等于列”,写在 JOIN 的 ON 子句中,由数据库引擎先生成两表的组合再按条件筛选。

SQL中如何实现非等值连接查询?在ON子句用范围判断或不等号的方法

一、非等值连接的基本写法

非等值连接的核心就是在 ON 后面使用比较运算符,而不是等号。最常见的场景是“打标签”或者“找相对关系”。比如有一张员工表 emp 和一张工资等级表 salgrade,后者用 losal 和 hisal 框定了每个等级的金额范围,我们想把每个员工的工资对应到等级,就可以用工资 BETWEEN 下限 AND 上限来连。

下面这段 SQL 展示了最基本的区间型非等值连接。它不会要求 emp.sal 等于某行 salgrade 的主键,而是判断落在哪个区间,因此同一张 salgrade 表可以被反复匹配,这是和等值连接语义上的最大不同。

SELECT
    e.ename,
    e.sal,
    s.grade
FROM emp e
JOIN salgrade s
  ON e.sal >= s.losal
 AND e.sal <= s.hisal;

另一个常见需求是“自己比自己”,例如找出工资高于部门平均工资的员工。这种也可以用非等值连接配合聚合结果来做,而不一定非要用子查询。不过要注意,非等值连接容易产生较大的中间结果集,尤其是两边都是大表时,笛卡尔积膨胀会非常明显。

二、使用不等于号的非等值连接

不等于(<> 或 !=)也是一种非等值条件,常用于排除自身或者排除某些关联行。典型例子是员工表里找“入职比自己早且工资比自己低”的同事组合,用来做配对分析。此时 ON 里写的是日期小于、工资大于再加一个工号不等。

以下示例用 emp 表自连接,通过不等于工号来避免自己和自己比较,同时用范围判断筛选前后辈关系。这种写法比用 WHERE 里加条件更清晰,因为连接逻辑都收拢在 ON 里,后续如果改成外连接也只需要动 JOIN 类型。

SELECT
    a.ename AS 前辈,
    b.ename AS 后辈
FROM emp a
JOIN emp b
  ON a.hiredate < b.hiredate
 AND a.empno <> b.empno
 AND a.sal > b.sal;

不等于号连接的风险在于它几乎无法利用常见的等值索引,多数情况下只能做全表扫描加过滤。如果业务允许,尽量把不等于转换成“小于某个值或大于某个值”的区间,或者配合其他等值条件缩小数据集,否则线上查询很容易超时。

三、范围判断连接与性能注意点

用 BETWEEN、>、< 做范围判断时,数据库优化器通常只能对其中一个边界使用索引,另一个边界仍要逐行比对。以订单表 orders 和汇率表 rates 为例,订单成交日要落到某个汇率生效区间内,就需要在 ON 里写 orders.trade_date >= rates.start_date 并且 <= rates.end_date。

下面代码演示了这种时间区间连接。如果 rates 表很小,数据库多半会选择把 rates 全量读入内存再遍历 orders;但如果 rates 也很大,就要考虑在 start_date、end_date 上建索引,或者把闭区间改成预计算好的日期映射表,用等值连接代替非等值连接来提升速度。

SELECT
    o.order_id,
    o.trade_date,
    r.currency,
    r.rate
FROM orders o
JOIN rates r
  ON o.trade_date >= r.start_date
 AND o.trade_date <= r.end_date;

从执行计划角度看,非等值连接往往出现 MERGE JOIN 或 NESTED LOOP 且无索引驱动的情况。写这类 SQL 时,建议先用小数据量 EXPLAIN 看是否产生了不合理的笛卡尔积,再把能等值化的条件(如币种相等)提前放到 ON 里,和非等值条件用 AND 组合,既保留业务逻辑又给优化器留出索引使用的空间。

四、与 WHERE 过滤的区别

有人会把非等值条件写在 WHERE 而不是 ON 里,在外连接场景下这两者结果完全不同。ON 里的条件决定“能不能连上”,连不上时右表字段为 NULL;WHERE 里的条件是在连完之后才过滤,可能把本该保留的 NULL 行删掉。所以只要是描述两表如何匹配的,都应放在 ON。

我们用左连接举例:想保留所有员工,哪怕没对应工资等级,等级条件就必须写在 ON。若错写到 WHERE,那些没有等级的人会因为 s.grade IS NULL 被过滤,业务含义就变了。下面是一个正确写法的片段,注意 ON 同时承载了区间与可选的等值条件。

SELECT
    e.ename,
    s.grade
FROM emp e
LEFT JOIN salgrade s
  ON e.sal >= s.losal
 AND e.sal <= s.hisal;

总结来说,非等值连接不是语法难点,而是建模思路的扩展。只要记住“匹配规则写在 ON,比较符号代替等号,注意数据集膨胀和索引利用”这三件事,就能在报表、区间映射、前后关系比对等场景里稳定地使用它。

SQL非等值连接ON子句修改时间:2026-08-02 16:33:34

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。