WHERE 子句的基本写法和常见错误
MySQL 中
WHERE子句必须紧跟在
SELECT、
UPDATE或
DELETE语句之后,用于过滤行。最基础的结构是:
WHERE column = value。容易出错的是把字符串值不加引号,比如写成
WHERE name = zhangsan(正确应为
WHERE name = 'zhangsan'),这会导致 MySQL 报错
Unknown column 'zhangsan' in 'where clause'。 数字类型字段可不加引号,如
id = 123字符串、日期类型必须用单引号包裹,如
name = 'Alice'、
created_at = '2024-01-01'
NULL值不能用
=判断,必须用
IS NULL或
IS NOT NULL多个条件用
AND/
OR连接,注意运算优先级;建议用括号明确逻辑,如
WHERE (status = 'active') AND (score > 80)
LIKE 模糊匹配要注意转义和性能
LIKE是
WHERE中高频但易误用的操作符。通配符
%(任意长度)和
_(单个字符)必须配合引号使用,例如
WHERE username LIKE 'admin%'。如果要查本身含
%的字面量,得用
ESCAPE指定转义符:
WHERE comment LIKE '%100\% off%' ESCAPE '\'前导通配符(如
LIKE '%abc')无法走索引,查询会变慢 想查固定前缀时尽量用
LIKE 'abc%',这样能命中 B+ 树索引 区分大小写取决于字段的 collation;若需强制不区分,可用
LOWER(column) LIKE LOWER('ABC%'),但会丢失索引
IN 和 BETWEEN 的适用边界
IN适合枚举少量离散值,
BETWEEN专用于闭区间连续范围。二者语法简洁,但行为差异明显:
WHERE id IN (1, 5, 9)等价于
WHERE id = 1 OR id = 5 OR id = 9;值过多(如超千个)会导致解析慢,建议分批或改用临时表
WHERE created_at BETWEEN '2024-01-01' AND '2024-12-31'包含两端,等价于
>= AND ;注意时间字段含时分秒时,<code>'2024-12-31'实际是
'2024-12-31 00:00:00',可能漏掉当天其他时间的数据
BETWEEN对字符串也有效,但按字符集排序规则比较,比如
WHERE name BETWEEN 'A' AND 'M'可能不包含带重音的 'Á'
WHERE 条件中函数调用的隐患
在
WHERE左侧对字段使用函数(如
WHERE YEAR(created_at) = 2024)会让该字段无法使用索引,即使
created_at上建了索引也没用。 应改为范围写法:
WHERE created_at >= '2024-01-01' AND created_at类似地,
WHERE UPPER(name) = 'JOHN'应改为
WHERE name = 'JOHN'并确保字段 collation 不区分大小写(如
utf8mb4_0900_as_cs区分,
utf8mb4_0900_ai_ci不区分) 只有当函数作用于常量一侧时才安全,如
WHERE status = UPPER('active')
实际写 WHERE 时,最常被忽略的是:日期字段没考虑时区和精度、字符串比较未确认 collation、以及对字段用函数导致索引失效——这些不会报错,但会让查询从毫秒变秒级。 