STR_TO_DATE 是 MySQL 特有函数,需严格匹配格式符与字符串,否则静默返回 NULL;常用于日期清洗,但易因空格、大小写、时区或宽松模式导致隐性错误。

STR_TO_DATE 不是标准 SQL 函数,它是 MySQL 特有的字符串转日期函数,用错语法或格式符会直接返回 NULL,且不报错——这是最常踩的坑。
STR_TO_DATE 语法和格式符必须严格匹配
它要求字符串内容和格式模板(format string)逐字符对齐。比如 '2023-05-12' 要用 '%Y-%m-%d',写成 '%y-%m-%d'(小写 %y 表示两位年份)就会失败。
-
STR_TO_DATE('12/05/2023', '%d/%m/%Y')✅ -
STR_TO_DATE('12/05/2023', '%m/%d/%Y')❌ 返回NULL(月份和日位置反了) -
STR_TO_DATE('2023-05-12 14:30', '%Y-%m-%d %H:%i')✅ -
STR_TO_DATE('2023-05-12 14:30', '%Y-%m-%d %h:%i')❌%h是 12 小时制,没 AM/PM 会解析失败
常见错误:把 STR_TO_DATE 当成 DATE 或 CAST 用
它不是类型转换函数,而是“按模板硬解析”。如果源字符串含非法值(如 '2023-02-30'),MySQL 默认静默返回 NULL,不会抛异常——你得靠 IS NULL 主动检查。
- 别写:
WHERE date_col = STR_TO_DATE('2023-02-30', '%Y-%m-%d')→ 结果永远不匹配 - 要写:
WHERE STR_TO_DATE(str_col, '%Y-%m-%d') IS NOT NULL AND ... - 注意时区:STR_TO_DATE 输出的是无时区的
DATE或DATETIME,不自动转当前会话时区
和 STR_TO_DATE 配合使用的典型场景
多见于导入 CSV、日志文本或用户输入的日期字段清洗,尤其当数据格式混乱时:
- 从日志中提取
'[2023/Apr/15 10:22:03]'→STR_TO_DATE(SUBSTRING(log_line, 2, 13), '%Y/%b/%d %H:%i:%s') - 统一处理多种格式:
COALESCE(STR_TO_DATE(s, '%Y-%m-%d'), STR_TO_DATE(s, '%d.%m.%Y'), STR_TO_DATE(s, '%m/%d/%Y')) - 注意性能:在 WHERE 或 JOIN 条件里频繁调用 STR_TO_DATE 会导致索引失效,建议先清洗存入规范列
真正麻烦的不是语法记不住,而是格式符和实际字符串之间那些看不见的空格、不可见字符、大小写(比如 %b 要求英文缩写全小写)、以及 MySQL 的宽松模式开关(sql_mode 含 ALLOW_INVALID_DATES 时连 2 月 30 日都可能被接受)。

















