
一、日期函数在日常做报表、统计同比环比、筛选时间段使用频次最高整理常用函数、语法、业务实例。1. curdate() 获取当前日期返回yyyy-MM-dd格式当日日期SELECT CURDATE(); -- 输出2026-07-092. now() 获取完整时间返回yyyy-MM-dd HH:mm:ss带时间戳的日期SELECT NOW(); -- 输出2026-07-09 09:56:49.03. date_add(日期, 间隔天数)日期向后偏移加天数SELECT DATE_ADD(CURDATE(),1);-- 获取明日日期SELECT DATE_ADD(CURDATE(),30);-- 获取30天之后日期4. date_sub(日期, 间隔天数)日期向前偏移减天数SELECT DATE_SUB(CURDATE(),1);-- 获取昨日日期业务常用做昨日数据筛选5. add_months(日期, 月份数)正数往后加月份负数往前减月份SELECT ADD_MONTHS(CURRENT_DATE, -1); -- 上月今日SELECT ADD_MONTHS(CURRENT_DATE, -12); -- 去年今日同比计算常用6. date_format(日期,格式)日期格式化分组统计必备SELECT DATE_FORMAT(CURDATE(),%Y-%m-01); -- 月初SELECT DATE_FORMAT(CURDATE(),%Y-%m-%d); -- 今天标准日期SELECT * FROM send_recordWHERE substr(post_date,1,10) between date_format(add_months(date_sub(current_date(),1),-1),%Y-%m-01)and date_format(add_months(date_sub(current_date(),1),-1),%Y-%m-%d) --昨天数据的上月同期SELECT * FROM send_recordWHERE DATE_FORMAT(send_date,%Y-%m) DATE_FORMAT(ADD_MONTHS(CURRENT_DATE,-1),%Y-%m); --上月数据7. datediff(结束日期,起始日期)计算两日期间隔天数SELECT SUM(CASE WHEN DATEDIFF(current_date(), substr(post_date,1,10)) 15 THEN 1 ELSE 0 END) AS 15天超期 ; --超期预警8. year()、month()、day() 拆分年月日用于按月、按年分组统计数据SELECT YEAR(curdate()),MONTH(curdate()),DAY(curdate()); --2026 7 99. weekofyear(date) 获取本年第几周SELECT WEEKOFYEAR(CURDATE()); --28WEEK(日期,模式)获取本年第几周可自定义一周起始日-- WEEK(date,1)周一算作一周首日报表最常用SELECT WEEK(CURDATE(),1); --2810. quarter() 获取季度SELECT QUARTER(CURDATE()); --311. DAYOFYEAR()获取当日是本年度第几天做长周期统计SELECT DAYOFYEAR(CURDATE()); --19012. WEEKDAY(date)规则周一0周日6SELECT WEEKDAY(CURDATE()); --3/*0 周一1 周二2 周三3 周四4 周五5 周六6 周日*/13. DAYOFWEEK(date)规则周日1周六7SELECT DAYOFWEEK(CURDATE()); --5二、常用单行函数及案例1. 空值判断函数1ifnull(字段,默认值)字段为NULL时替换为自定义数值报表避免空单元格-- 退件为空统一赋值0SELECT IFNULL(return_num,0) FROM send_record;-- where条件加上空值判断避免漏数据where ifnull(entrust_name,) not like %测试%sum(字段)、avg(字段)不会统计null只有count(*)统计全部行count(字段)不计入空值。实操避坑统计单据总量优先count(send_no)统计含空记录行数使用count(*)isnull()函数ISNULL(字段)为空返回1不为空返回0SELECT ISNULL(sign_time) FROM send_record;左连接查询出来右侧字段null除IFNULL还可以在where、having阶段过滤空数据-- 筛选所有未签收单据SELECT a.send_no FROM send_record aLEFT JOIN sign_info b ON a.send_no b.send_noWHERE b.send_no IS NULL;2coalesce() 多字段依次判空-- 优先取退件数为空取异常件都为空填0SELECT COALESCE(return_num,error_num,0) FROM send_record;2. 字符串函数1length() 获取字符长度SELECT LENGTH(cust_name) FROM send_record;2substr() 字符串截取-- 截取手机号前三位SELECT SUBSTR(phone,1,3) FROM send_record;3. 聚合函数分组统计必备sum、count、avg、max、min-- 统计本月总发函量、单据条数SELECT SUM(send_num),COUNT(send_no) FROM send_record;-- 单月最大单日发函、最小发函数量SELECT MAX(send_num),MIN(send_num) FROM send_record;-- 去重计数统计不重复发函单号SELECT count(distinct send_num) FROM send_record;4. 字符串函数1 concat()字段拼接拼接省份与单据编号SELECT CONCAT(province,_,send_no) AS prov_send FROM send_record;2 concat_ws()带分隔符拼接比concat更实用SELECT CONCAT_WS(-,province,cust_name,send_no) FROM send_record;3 upper()、lower()大小写转换SELECT UPPER(cust_addr),LOWER(cust_addr) FROM send_record;4 trim()、ltrim()、rtrim()去除首尾空格清洗脏数据-- 去除客户姓名两端空格SELECT TRIM(cust_name) FROM send_record;5 instr()查询字符首次出现位置SELECT INSTR(phone,7) FROM send_record;6 replace()字段内容替换脱敏手机号SELECT REPLACE(phone,SUBSTR(phone,4,4),****) FROM send_record;7 lpad()、rpad()左右补位统一单据编码长度SELECT LPAD(send_no,10,0) FROM send_record;5. 数值数学函数1 round() 四舍五入计算签收率保留两位小数SELECT ROUND(SIGN_COUNT/SEND_COUNT*100,2) AS sign_rate FROM send_record;2 ceil() 向上取整、floor()向下取整SELECT CEIL(12.1),FLOOR(12.9); -- 13 、123 mod() 取余数单号奇偶分类SELECT MOD(send_no,2) FROM send_record;4 abs() 绝对值处理异常负数数据SELECT ABS(error_num) FROM send_record;6. 条件判断函数1 if() 简易判断简化单层case when语法IF(判断条件,成立返回值,不成立返回值)SELECT send_no,IF(sign_time IS NULL,未签收,已签收) AS sign_state FROM send_record;2 nullif(a,b) 两个字段相等返回null不等返回第一个字段SELECT NULLIF(send_num,return_num) FROM send_record;7. 窗口函数数据分析中做排名、行号、分区统计1. row_number() 不重复排名SELECT send_no,send_num,ROW_NUMBER() OVER(PARTITION BY province ORDER BY send_num DESC) AS rnFROM send_record;2. rank()、dense_rank() 并列排名三、其他1. 四种表连接方式附带业务案例现有两张表send_record发函主表单据号、发函日期、寄件省份sign_info签收附表单据号、签收时间、签收状态关联字段单据号 send_no1 内连接 inner join可简写join只返回两张表可以匹配上的数据丢弃无签收记录单据SELECT a.send_no,a.send_date,b.sign_statusFROM send_record aINNER JOIN sign_info bON a.send_no b.send_no;2 左连接 left join日常数据分析使用最多以左表发函表为全部基准所有发函单据全部保留没有签收记录右侧字段填充NULLSELECT a.send_no,a.send_date,IFNULL(b.sign_status,未签收)FROM send_record aLEFT JOIN sign_info bON a.send_no b.send_no;业务用处统计全部发函单据区分已签收、未签收数据计算签收率。3 右连接 right join以右侧签收表为基准展示所有签收记录无对应发函单据左侧为空工作场景偏少。4 全连接 full join展示两张表全部数据无法匹配字段统一为空。