MySQL 中
IN语句是实现多值条件查询最常用、最直观的方式,适用于“字段值属于某几个指定值之一”的场景。
IN 语句的基本语法和用法
IN用于
WHERE子句中,后面跟一个括号,括号内是一组用逗号分隔的常量值(支持数字、字符串、NULL 等),也可替换为子查询结果。
示例:
SELECT * FROM users WHERE status IN ('active', 'pending');
SELECT * FROM orders WHERE user_id IN (101, 105, 203);
注意:字符串值必须加单引号;数值可不加,但统一加引号更安全(尤其配合参数化查询时)。
与 OR 的等价性与性能差异
上面的
status IN ('active', 'pending') 等价于:status = 'active' OR status = 'pending'。
但
IN更简洁、可读性更强,且 MySQL 优化器通常能对
IN列表做更好处理(尤其是配合索引时)。不过当列表过大(如几千个值),性能可能下降,此时建议改用临时表或 JOIN。
配合子查询动态生成条件
IN支持子查询,适合“查 A 表中在 B 表里存在对应记录的数据”这类需求: 推荐写法(单列子查询):
SELECT name FROM users WHERE id IN (SELECT user_id FROM orders WHERE amount > 100);注意限制:子查询必须返回**单列**,且数据类型需与左侧字段兼容;若子查询结果含
NULL,整条
IN判断可能意外失效(
expr IN (..., NULL)返回
NULL,不匹配
TRUE),建议显式排除:
... WHERE id IN (SELECT user_id FROM orders WHERE user_id IS NOT NULL AND amount > 100);
常见坑点与注意事项
空列表不合法:WHERE id IN ()是语法错误,程序中需判断列表是否为空,为空时跳过该条件或用
WHERE 1=0代替 NULL 值无法匹配:
col IN (1, 2, NULL)不会匹配
col IS NULL,因为
col = NULL永远为
UNKNOWN。要查 NULL 需单独写:
col IN (1, 2) OR col IS NULL大数据量慎用长列表: 超过 1000 个值时,建议拆分或改用
JOIN或临时表,避免 SQL 过长、解析慢、内存占用高
