EXTRACT
函数搞定这些烦心事,顺便甩几个MySQL里的神操作!真实踩坑:同事小王上周熬夜写报表,死活算不出月度增长率… 最后发现是月份数提取错了——他居然用字符串截取
substring(date,6,2)
,结果2月变成“02”被当成八进制数字!🤯
一、5分钟搞懂EXTRACT函数底层逻辑
虽然EXTRACT
听起来高大上,但其实它就是个“日期拆弹专家”💣!专门把时间数据里的年、月、日、小时这些零件拆出来给你用。
语法简单得不要不要的:
sql复制SELECT EXTRACT(单位 FROM 日期字段) FROM 表名;
比如想从订单时间order_date
里扒出年份:
sql复制SELECT EXTRACT(YEAR FROM order_date) AS 下单年份 FROM orders; -- 返回2025
注意坑位:
- 在SQL Server里这招行不通!得用
YEAR(order_date)
;- 而Oracle更怪,要用
EXTRACT(YEAR FROM order_date)
但语法略有不同。
二、MySQL实战:4个场景吊打报表需求
✅ 场景1:计算会员生日季度分布
领导想知道会员生日集中在哪个季度?用QUARTER
参数一键搞定:
sql复制SELECTEXTRACT(QUARTER FROM birthday) AS 生日季度,COUNT(*) AS 人数FROM usersGROUP BY 生日季度; -- 1=Q1春季,2=Q2夏季...
省心技巧:比用
MONTH
算完再除4省事多了!
✅ 场景2:统计凌晨下单的夜猫子
电商运营常要分析用户活跃时段:
sql复制SELECT
user_id,
EXTRACT(HOUR FROM order_time) AS 下单小时FROM ordersWHERE EXTRACT(HOUR FROM order_time) BETWEEN 0 AND 6; -- 筛选0~6点订单
避坑指南:别直接
WHERE 下单小时>0
!分组过滤必须用HAVING,否则报错!
✅ 场景3:拼接年月生成报表标题
需要“2025年07月”这样的标题?试试组合拳:
sql复制SELECT
CONCAT(
EXTRACT(YEAR FROM create_time), '年',EXTRACT(MONTH FROM create_time), '月') AS 报表月份 -- 输出"2025年07月" FROM sales;
血泪教训:月份小于10时别忘补零!否则“7月”排序会乱(07 vs 7)🔢
三、90%人不知道的隐藏玩法
🔥 玩法1:秒算工龄(精确到天)
sql复制SELECT name,EXTRACT(DAY FROM NOW() - hire_date) AS 入职天数 -- 直接相减再提取天数 FROM employees;
比
DATEDIFF
更直观!但注意跨年时月份会重置,别用来算薪资!
🔥 玩法2:自动忽略过期数据
sql复制DELETE FROM logsWHERE EXTRACT(YEAR FROM log_time) < 2025; -- 删掉2025年前的旧数据
危险操作:生产环境先
SELECT
测试!误删会哭晕😭
四、高阶玩家秘籍:时间截取 + 条件判断
想统计“工作日晚间19-22点订单量”?试试CASE WHEN
组合技:
sql复制SELECTCASEWHEN EXTRACT(HOUR FROM order_time) BETWEEN 19 AND 22 THEN '晚间高峰'WHEN EXTRACT(HOUR FROM order_time) BETWEEN 11 AND 13 THEN '午间小高峰'ELSE '普通时段'END AS 时段标签,COUNT(*) AS 订单量FROM ordersWHERE EXTRACT(DOW FROM order_time) NOT IN (6,7) -- DOW=星期几(0=周日,1=周一...) GROUP BY 时段标签;
冷知识:
MySQL的EXTRACT(DOW)
返回0-6(0=周日),但PostgreSQL返回1-7(1=周一)!跨库迁移时必查!
最后甩个王炸案例
财务部要“按周统计回款”,你还在手动算周数?
sql复制SELECTEXTRACT(WEEK FROM payment_date) AS 周号, -- 全年第几周 SUM(amount) AS 回款总额FROM paymentsGROUP BY 周号;
结果直接对接Excel周报📊,效率翻倍不加班!