extract可提取year、month、day、hour、minute、second等标准时间单位,postgresql等还支持quarter、dow等;返回数值而非字符串,大小写敏感(postgresql须大写),不支持多字段一次提取。

EXTRACT 能提取哪些时间部分?
EXTRACT 是标准 SQL 函数,用于从 TIMESTAMP、DATE 或 TIME 类型中抽取指定的时间单位。它不返回格式化字符串,只返回整数——比如 EXTRACT(YEAR FROM '2024-03-15') 返回 2024(不是字符串 '2024'),EXTRACT(HOUR FROM '14:30:00') 返回 14。
常见可提取字段包括:YEAR、MONTH、DAY、HOUR、MINUTE、SECOND;部分数据库(如 PostgreSQL)还支持 QUARTER、DOW(星期几)等。
注意:大小写敏感性依数据库而定——PostgreSQL 要求大写(YEAR),MySQL 8.0+ 和 SQLite 支持大小写不敏感,但统一用大写更安全。
如何同时提取年、月、小时并组合成新字段?
不能直接写 EXTRACT(YEAR, MONTH, HOUR FROM col) ——语法错误。EXTRACT 每次只能取一个字段,需多次调用并用表达式拼接。
- 若目标是生成类似
2024-03-14(年月日)或2024-03 14:00这种可读格式,应搭配字符串函数(如TO_CHAR(PostgreSQL)、DATE_FORMAT(MySQL)),而非硬凑EXTRACT - 若只需数值计算(例如按年月分组统计),直接多列
EXTRACT即可:
SELECT EXTRACT(YEAR FROM occurred_at) AS y, EXTRACT(MONTH FROM occurred_at) AS m, EXTRACT(HOUR FROM occurred_at) AS h, COUNT(*) FROM events GROUP BY y, m, h;
PostgreSQL 和 Oracle 支持在 GROUP BY 中直接写 EXTRACT(...),但 MySQL 5.7 不允许(需用别名或重复表达式)。
不同数据库对 EXTRACT 的支持差异
不是所有数据库都原生支持 EXTRACT:
- PostgreSQL:完全支持,语法最标准
- Oracle:支持,但
EXTRACT(HOUR FROM ...)要求输入是TIMESTAMP,DATE类型会报错(ORA-30076: invalid extract field for extract source) - MySQL:8.0+ 才支持
EXTRACT;之前版本得用YEAR()、MONTH()、HOUR()等专用函数 - SQLite:不支持
EXTRACT,必须用strftime('%Y', col)、strftime('%m', col)、strftime('%H', col) - SQL Server:无
EXTRACT,改用YEAR()、MONTH()、DATEPART(HOUR, col)
跨库迁移时,别盲目套用 EXTRACT ——先确认目标数据库版本和类型。
为什么用 EXTRACT 而不用字符串截取?
有人试图用 SUBSTR(col, 1, 4) 取年份,这在 col 是 TEXT 且格式固定(如 '2024-03-15 14:22:01')时看似可行,但风险极高:
- 字段类型是
TIMESTAMP时,SUBSTR会触发隐式转换,结果依赖数据库的默认格式(可能变成'15-MAR-24 02.22.01.000000 PM') - 时区信息、毫秒、本地化格式(如德语月份缩写)会让截取彻底失效
-
EXTRACT基于逻辑时间值运算,与时区、格式、存储精度无关
真正需要年月小时数值参与计算或分组时,EXTRACT 是唯一健壮的选择;只要记住它不输出字符串,也不处理格式——那是 TO_CHAR 或 FORMAT 的事。










