最稳妥方式是调用数据库内置日期函数:mysql用year()/month()/day(),postgresql用extract()或to_char(),sql server用datepart()或format(),sqlite用strftime()或substr(),字符串类型需先转日期。

MySQL 中用 YEAR()、MONTH()、DAY() 拆分日期
直接从 DATE 或 DATETIME 字段里取年月日,最稳妥的方式是调用内置函数。注意这些函数只接受合法日期值,传入 NULL 或非法字符串(如 '2023-13-01')会返回 NULL,不会报错但结果不可靠。
-
YEAR(date_col)返回 4 位整数,比如2023 -
MONTH(date_col)返回 1–12 的整数,不是补零格式(要05得用LPAD(MONTH(...), 2, '0')) -
DAY(date_col)同理,返回 1–31 整数 - 如果字段是字符串类型(如
VARCHAR存的'2023-05-21'),先用STR_TO_DATE(date_str, '%Y-%m-%d')转成日期再提取,否则函数返回NULL
PostgreSQL 里用 EXTRACT() 和 TO_CHAR()
PostgreSQL 不提供 YEAR() 这类简写函数,统一用 EXTRACT(),返回数值;需要字符串格式(如带前导零的月份)就得用 TO_CHAR()。
-
EXTRACT(YEAR FROM date_col)→ 返回2023.0(浮点数),常配合::INT转整型:EXTRACT(YEAR FROM date_col)::INT -
TO_CHAR(date_col, 'YYYY-MM-DD')一次性输出标准格式字符串,适合导出或展示 -
TO_CHAR(date_col, 'MM')返回'05','M'才返回'5';大小写敏感,'yyyy'会报错 - 时区会影响结果:若字段是
TIMESTAMP WITH TIME ZONE,EXTRACT按当前会话时区计算,不是存储时区
SQL Server 的 DATEPART() 和 FORMAT()
DATEPART() 是最常用也最兼容的方案,支持所有 SQL Server 版本;FORMAT() 功能强但性能差,仅建议在展示层用。
-
DATEPART(year, date_col)、DATEPART(month, date_col)、DATEPART(day, date_col)返回整数 -
FORMAT(date_col, 'yyyy-MM-dd')返回字符串,注意格式符大小写:'yyyy'是 4 位年,'yy'是 2 位;'MM'补零,'M'不补 -
FORMAT()在 SQL Server 2012+ 可用,但会显著拖慢大数据量查询,别在 WHERE 或 JOIN 条件里用 - 如果字段是
datetime2,DATEPART行为和datetime一致,无需额外处理
跨数据库可移植的写法:用字符串截取凑合用
当无法确定目标数据库类型,或只处理标准 YYYY-MM-DD 格式字符串时,字符串函数反而最通用——但前提是数据格式绝对统一。
- 假设字段
date_str值恒为'2023-05-21',可用SUBSTRING(date_str, 1, 4)取年,SUBSTRING(date_str, 6, 2)取月,SUBSTRING(date_str, 9, 2)取日 - SQLite 没有
YEAR()函数,只能靠SUBSTR()或strftime('%Y', date_col)(后者仅限日期能被 SQLite 识别) - 风险点:一旦出现
'2023-5-21'或'2023/05/21',所有SUBSTRING都失效;strftime对非标准格式直接返回NULL
DESCRIBE table_name 一看是 VARCHAR,后面全白忙。











