year()函数仅支持date/datetime/timestamp类型,字符串需用str_to_date()显式转换;int型年月日应取整除10000;where中使用year()会导致索引失效,应改用日期范围查询。

YEAR() 函数直接提取年份,但要注意输入类型
MySQL 的 YEAR() 函数只接受 DATE、DATETIME 或 TIMESTAMP 类型值,传入字符串会触发隐式转换——看似能用,实则埋雷。比如 '2023-10-05' 这种标准格式能转成功,但 '05/10/2023' 或 '20231005' 很可能转成 0000 或报错。
- 安全做法是先用
STR_TO_DATE()显式转成日期,再套YEAR(),例如:YEAR(STR_TO_DATE('05/10/2023', '%d/%m/%Y')) - 如果字段本身就是
DATE类型(如order_date),直接写YEAR(order_date)最稳 - 对
INT类型存的 20231005 这种,别硬套YEAR(),改用FLOOR(col / 10000)
WHERE 条件里用 YEAR() 可能导致索引失效
在查询条件中写 WHERE YEAR(create_time) = 2023,哪怕 create_time 有索引,MySQL 通常也无法有效利用——因为函数作用于列,优化器没法做范围下推。
- 正确写法是用日期范围:
WHERE create_time >= '2023-01-01' AND create_time - 如果必须按年聚合统计,
GROUP BY YEAR(create_time)没问题,但 WHERE 过滤仍建议避开函数 - 临时表或视图里用
YEAR()做派生列可以,但别指望它加速过滤
YEAR() 对非法日期返回 0,不是 NULL
YEAR() 遇到无效日期(如 '2023-13-01'、'0000-01-01' 或 NULL)时,统一返回 0,而不是报错或返回 NULL。这容易掩盖数据质量问题。
- 检查数据是否合法,优先用
IS_VALID_DATE()(MySQL 8.0.29+)或STR_TO_DATE()是否为 NULL - 如果业务上不允许年份为 0,记得加过滤:
WHERE YEAR(date_col) > 0 - 导出报表时发现一堆 “0” 年份,大概率是原始数据里混了脏日期或空字符串
YEAR() 写得对不对,先盯住字段类型和查询意图。











