在SQL查询场景中,判断同一行记录里两列数据是否相同是高频需求,最常见的实现方式就是在WHERE子句中直接对两列进行条件对比,这种方式简单直接,能快速筛选出符合要求的记录。

基础列对比语法
最基础的列对比逻辑是使用等号=运算符,直接比较两列的值是否相等,语法格式如下:
-- 查询表table_name中col1和col2值相同的所有记录 SELECT * FROM table_name WHERE col1 = col2;
如果要查询两列值不同的记录,只需要将等号替换为不等号<>或者!=即可,不同数据库对这两种不等号的兼容性略有差异,<>的通用性更强:
-- 查询表table_name中col1和col2值不同的所有记录 SELECT * FROM table_name WHERE col1 <> col2;
空值场景的特殊处理
需要注意SQL中NULL值的对比规则:NULL与任何值(包括NULL本身)使用等号对比的结果都是NULL,不会被判定为相等,因此如果列中可能存在NULL值,直接使用=对比会漏掉两列都为NULL的记录。
如果需要将两列都为NULL的情况也判定为相同,需要额外添加空值判断条件,通用写法如下:
-- 查询col1和col2相同,包含两列都为NULL的场景 SELECT * FROM table_name WHERE col1 = col2 OR (col1 IS NULL AND col2 IS NULL);
部分数据库提供了更简洁的空值对比函数,比如MySQL的<=>运算符,它会将NULL视为可比较的值,两列都为NULL时返回true:
-- MySQL专用写法,直接对比包含NULL的两列 SELECT * FROM table_name WHERE col1 <=> col2;
不同数据库的兼容差异
不同数据库对列对比的支持存在细微差异,以下是常见数据库的实现说明:
| 数据库类型 | 基础等号对比 | 空值安全对比方式 |
|---|---|---|
| MySQL | 支持=和<> | 支持<=>运算符 |
| PostgreSQL | 支持=和<> | 支持IS NOT DISTINCT FROM语法 |
| Oracle | 支持=和<> | 支持DECODE函数或NVL函数处理空值 |
| SQL Server | 支持=和<> | 支持ISNULL函数处理空值 |
实际场景示例
假设存在用户表user_info,包含id、register_email、bind_email三个字段,需要查询注册邮箱和绑定邮箱相同的用户,同时包含两者都为空的记录,通用SQL写法如下:
SELECT id, register_email, bind_email FROM user_info WHERE register_email = bind_email OR (register_email IS NULL AND bind_email IS NULL);
如果是PostgreSQL数据库,也可以使用空值安全对比语法简化:
SELECT id, register_email, bind_email FROM user_info WHERE register_email IS NOT DISTINCT FROM bind_email;
常见注意事项
- 对比的两列数据类型需要兼容,比如数值型和字符型对比可能会触发隐式类型转换,导致索引失效,建议提前确认列类型一致。
- 如果列中存在大量NULL值,建议先明确业务是否需要将NULL视为相等,再选择对应的对比逻辑,避免结果不符合预期。
- 在WHERE子句中使用函数处理列值(比如
NVL(col1,0) = NVL(col2,0))会导致列上的普通索引无法使用,数据量大的表需要谨慎使用。