MySQL 函数速查表:快速通过在线SQL测试

本文总结了Oracle转MySQL时需注意的核心函数差异,重点解析了日期处理、NULL值处理、条件判断等高频考点函数的使用方法。


关键点包括:

  1. MySQL日期函数如NOW()、DATEDIFF()的用法及与Oracle的对比;

  2. NULL处理的IFNULL()和COALESCE()函数区别;

  3. 字符串拼接必须使用CONCAT而非||;

  4. DATEDIFF()会自动忽略时分秒,TIMESTAMPDIFF()可计算精确时间差。


文章通过典型场景示例和易错点分析,帮助开发者快速适应MySQL语法特点,提高SQL编写效率和正确性。


从 Oracle 转战 MySQL,最关键的差异就是函数名和 NULL 的处理方式。xxx的 SQL 在线评测通常使用 MySQL,掌握下表的核心函数可以帮你快速通过测试。


以下是做题时最常用到的 MySQL 函数总结:


📊 MySQL 核心函数速查表


(注:加粗函数为xxx高频考点)


1. 日期时间处理(必考)

功能分类 MySQL 函数 示例/说明 Oracle 对比 高频场景
获取当前时间 NOW() 返回日期和时间 2025-05-12 10:00:00 SYSDATE 记录操作时间
CURDATE() 返回当前日期 2025-05-12 TRUNC(SYSDATE) 按日期分组统计
日期差值 DATEDIFF(date1, date2) date1 - date2 的天数 (整数) date1 - date2 (直接减) 计算用户留存、逾期天数
日期加减 DATE_ADD(date, INTERVAL n UNIT) DATE_ADD('2025-05-01', INTERVAL 1 DAY) date + n 有效期推算,牛客题常用
格式化 DATE_FORMAT(date, format) DATE_FORMAT('2025-05-12, '%Y-%m')2025-05`[citation:1] TO_CHAR\ | 按月/年统计 |
提取部分 YEAR(date), MONTH(date) 直接提取年份或月份数字 EXTRACT(YEAR FROM date) 筛选特定月份数据

2. NULL 值处理(易错点)

功能分类 MySQL 函数 示例/说明 Oracle 对比 高频场景
空值转默认值 IFNULL(expr, default) exprNULL,返回default NVL 最常用,处理查询中的空值
条件判空 IS NULL / IS NOT NULL WHERE phone IS NULL 同MySQL 排查缺失数据
空值合并 COALESCE(val1, val2, ...) 返回第一个非空值 同MySQL 多字段优先级取值
判断后运算 NULLIF(expr1, expr2) 相等返回NULL,否则返回expr1 同MySQL 避免除零错误

IFNULL(expr, default)和COALESCE(val1, val2, ...)的核心区别:参数数量返回值类型推断

对比维度 IFNULL(expr, default) COALESCE(val1, val2, ...)
参数个数 固定 2个 至少1个,可多个
返回逻辑 第1个非NULL → 返回expr 否则 → 返回default 从左到右,返回第一个非NULL值
标准兼容性 MySQL特有函数 SQL标准函数 (Oracle/PostgreSQL/SQL Server都支持)
典型场景 简单二选一: IFNULL(score, 0) 多字段优先级: COALESCE(手机, 微信, 邮箱, '无联系方式')
一句话总结
  • 只有两个值处理空值 → 用 IFNULL(MySQL专属,更简洁)

  • 多个值取第一个非空 → 用 COALESCE(跨数据库通用,更强大)


3. 条件判断(逻辑核心)

功能分类 MySQL 函数 示例/说明 Oracle 对比 高频场景
简单条件 IF(condition, true_val, false_val) IF(score>=60, '及格', '不及格') DECODECASE 分值转换、等级划分
多路分支 CASE WHEN ... THEN ... END 通用性强,支持任意逻辑 同MySQL 复杂业务逻辑映射
行转列 IF()SUM(CASE...) 常配合聚合函数进行条件计数 PIVOT 交叉表统计 -> xxx必考

4. 字符串处理(数据清洗)

功能分类 MySQL 函数 示例/说明 Oracle 对比 高频场景
拼接 CONCAT(str1, str2, ...)CONCAT_WS(separator, ...) CONCAT(first_name, last_name) `
截取 SUBSTRING(str, pos, len) SUBSTRING('abcde', 2, 3)bcd SUBSTR 提取身份证、手机号片段
长度 CHAR_LENGTH(str) (字符数) / LENGTH(str) (字节数) 中文字符下长度不同 LENGTH 限制显示字数
大小写 UPPER(str) 转大写 同MySQL 统一格式比较
去除空格 TRIM([BOTH/LEADING/TRAILING] ... FROM str) 默认删除首尾空格 同MySQL 清洗用户输入数据
替换 REPLACE(str, from_str, to_str) 替换字符串中的内容 REPLACE 脱敏、格式化文本

5. 类型转换(避免踩坑)

功能分类 MySQL 函数 示例/说明 Oracle 对比 高频场景
隐式转换 CAST(expr AS type) CAST('123' AS SIGNED) TO_NUMBER / TO_CHAR 类型匹配防止SQL错误
显式转换 (简便) 直接加 +0 ORDER BY score+0 - 字符串字段按数值排序

6. 窗口函数(进阶必备,MySQL 8.0+)

功能分类 MySQL 函数 示例/说明 Oracle 对比 高频场景
排名 ROW_NUMBER() , RANK() , DENSE_RANK() 分组内排序编号 同MySQL 排名类题目 -> 最核心解法
前后取值 LAG(expr, offset) , LEAD(expr, offset) 访问当前行之前/之后的行数据 同MySQL 环比计算、差值分析

💡 刷题快速适应技巧

除了记函数,理解以下两点能避免很多"莫名奇妙"的错误:

  1. NULL 不参与运算 :在 MySQL 中,任何包含 NULL 的算术表达式结果都是 NULL 。例如 salary + NULL 的结果是 NULL。如果你想忽略 NULL 继续计算,必须用 IFNULL() 将其转为 0。

  2. 字符串拼接别用 || :Oracle 中用 || 拼接字符串,但在 MySQL 的默认模式下,'a' || 'b' 的结果是 0(因为 || 被视为逻辑或运算符)。一定要用 CONCAT('a', 'b') 函数

  3. 日期减法要小心 :在 Oracle 中 date1 - date2 直接返回天数,但在 MySQL 中这样写返回的是数字,但逻辑有时不直观。建议统一使用 DATEDIFF(date1, date2),这是最稳妥的做法。

  4. TOP-N 查询写法不同 :Oracle 用 ROWNUM <= 10 取前几条,MySQL 必须用 LIMIT n 放在 ORDER BY 后面,例如 ORDER BY score DESC LIMIT 3


DATE_FORMAT('2025-05-12, '%Y-%m') 为什么里面的Y是大写,m是小写


这是 MySQL 继承自 C 语言 strftime() 函数的标准格式 ,大小写分别代表不同的含义,不是随意设计的。


为什么 Y 大写,m 小写?

核心原因是:大写和小写代表不同的日期/时间部分,互不冲突。

格式符 含义 示例输出 为什么是这个大小写?
%Y 四位年份 (Year) 2025 Y 大写 → 完整的、长格式的年份
%y 两位年份 25 y 小写 → 简短、缩写形式的年份
%M 完整的月份名称 (Month) May M 大写 → 月份名称 (长)
%m 月份数字 (01-12) 05 m 小写 → 月份数字 (短)
%D 带英文后缀的日期 12th D 大写 → 带序数词的完整格式
%d 日期数字 (01-31) 12 d 小写 → 纯数字格式

这样设计的 2 个核心好处

  1. 一个字母表达多种格式

    用大小写区分,不需要发明两个不同的字母。例如 Yy 共享字母 Y,通过大小写告诉 MySQL 你要4位 还是2位年份。

  2. 月份和分钟不冲突

    月份(Month)和分钟(Minute)如果都用 m 就乱套了。所以:

    • %m = 月份 (Month)

    • %i = 分钟 (Minute) --- 注意,分钟用的不是 m,而是 i,彻底避开冲突。

最容易混淆的 3 个例子(刷题必看)

可能想当然的写法 实际正确写法 输出结果 错在哪
DATE_FORMAT(date, '%Y-%m') '%Y-%m' 2025-05 正确Y大写四位年份,m小写月份数字
DATE_FORMAT(date, '%y-%M') ❌ 不符合需求 25-May y小写→两位年份,M大写→完整月份名
想获取 May 12, 2025 '%M %d, %Y' May 12, 2025 月份名称用大写 M,日期数字用小写 d

一个记忆技巧(不用硬背)

  • 年份 :你想要长(4位)还是短(2位)?

    长 → 大写 Y --- 因为 Y 看起来很"大"

    短 → 小写 y --- 因为 y 看起来很"小"

  • 月份 :你想看到英文单词(长)还是数字(短)?

    英文单词 → 大写 M --- 因为单词比数字长

    数字 → 小写 m --- 因为数字短小

  • 分钟 :分钟 ≠ 月份 → 用 i(取 minute 里不冲突的字母 i)

实战建议

刷xxx题目时,不用背全表,记住最常用的这 3 个模式就够了:

sql

sql 复制代码
-- 1. 按年月分组统计 (最常见)
DATE_FORMAT(create_time, '%Y-%m')  -- 2025-05

-- 2. 按年月日分组
DATE_FORMAT(create_time, '%Y-%m-%d')  -- 2025-05-12

-- 3. 只取月份数字
MONTH(create_time)  -- 更简单

MONTH(date) 返回的是1,2,3 还是01,02,03呢


返回的是纯数字 1, 2, 3,不会补零。


验证一下

sql

复制代码
SELECT MONTH('2025-05-12')  -- 返回 5(没有前导0)
SELECT MONTH('2025-01-01')  -- 返回 1(不是01)

和 DATE_FORMAT 的对比

函数 输入 2025-05-12 返回结果 类型 补零?
MONTH(date) 2025-05-12 5 整数 ❌ 不补零
DATE_FORMAT(date, '%m') 2025-05-12 05 字符串 ✅ 补零

刷题时的影响

这个差异在以下场景会踩坑

❌ 错误示例(以为 MONTH 返回字符串)

sql

复制代码
-- 想把 5 和 '05' 拼接,结果不符合预期
SELECT CONCAT('月份是:', MONTH('2025-05-12'))  -- 返回 '月份是:5'(不是 '月份是:05')

✅ 正确做法

场景1:需要补零的显示格式

sql

复制代码
-- 用 DATE_FORMAT
SELECT DATE_FORMAT('2025-05-12', '%m')  -- '05'

-- 或者手动补零
SELECT LPAD(MONTH('2025-05-12'), 2, '0')  -- '05'

场景2:数值比较(直接相等判断)

sql

复制代码
-- ✅ MONTH 可以直接和数字比较
WHERE MONTH(create_time) = 5  -- 正确

-- ❌ 但别和字符串 '05' 比较(虽然 MySQL 会隐式转换,但不规范)
WHERE MONTH(create_time) = '05'  -- 能运行但不好

场景3:分组统计(不影响)

sql

复制代码
-- ✅ 按月份分组,MONTH 返回 1-12,完全够用
SELECT MONTH(order_date), COUNT(*)
FROM orders
GROUP BY MONTH(order_date)  -- 分组正确,不需要补零

一个记忆技巧

  • MONTH() → 返回 数字类型 (用于计算、比较、分组)→ 不补零

  • DATE_FORMAT(..., '%m') → 返回 字符串类型 (用于显示、拼接)→ 补零


快速对比例(方便记)

需求 用哪个函数 示例
筛选 5 月的订单 MONTH(date) = 5 WHERE MONTH(order_date) = 5
按月份分组统计 GROUP BY MONTH(date) GROUP BY MONTH(create_time)
显示成 05 DATE_FORMAT(date, '%m') SELECT DATE_FORMAT(order_date, '%m')
拼接成 2025-05 DATE_FORMAT(date, '%Y-%m') SELECT DATE_FORMAT(order_date, '%Y-%m')

一句话总结MONTH() 返回纯数字 1-12 ;想要带前导零的 01-12,必须用 DATE_FORMAT(date, '%m')


DATEDIFF(date1, date2)对其中的date1和date2的日期格式有要求吗,比如都带时分秒,或者不能有时分秒


没有严格要求 ,但建议 统一使用日期格式或只取日期部分,否则容易踩坑。


核心原理

DATEDIFF(date1, date2) 内部会自动提取日期部分,忽略时间(时分秒)。所以:

  • ✅ 格式不同也能正常计算

  • ✅ 带不带时分秒都可以

  • ⚠️ 但字符串格式错误会导致报错

各种情况实测

date1 date2 结果 说明
'2025-05-12' '2025-05-10' 2 ✅ 标准日期格式
'2025-05-12 23:59:59' '2025-05-10 00:00:00' 2 ✅ 自动忽略时分秒
'2025-05-12 23:59:59' '2025-05-12 00:00:01' 0 ✅ 同一天,时分秒不影响
'2025-05-12' '2025-05-10 18:30:00' 2 ✅ 混合格式也可以
'20250512' '20250510' 2 ✅ 纯数字字符串也能识别
'2025/05/12' '2025/05/10' 2 ✅ 斜杠分隔也能识别
'12-05-2025' '10-05-2025' NULL ❌ 非标准顺序会失败

3 个容易踩的坑

坑1:字符串格式不标准导致报错或 NULL

sql

复制代码
-- ❌ 错误:日期的顺序不对
SELECT DATEDIFF('12-05-2025', '10-05-2025');  -- 可能返回 NULL 或报错

-- ✅ 正确:使用标准格式 YYYY-MM-DD
SELECT DATEDIFF('2025-05-12', '2025-05-10');  -- 2

坑2:以为时间会影响结果(实际不会)

sql

复制代码
-- 虽然是同一天的不同时间,但 DATEDIFF 只看日期
SELECT DATEDIFF('2025-05-12 23:59:59', '2025-05-12 00:00:01');  -- 0(不是 1)

-- 如果真要按时间差计算天数,用 TIMESTAMPDIFF
SELECT TIMESTAMPDIFF(DAY, '2025-05-12 00:00:01', '2025-05-12 23:59:59');  -- 0(还是0,因为不足24小时)
SELECT TIMESTAMPDIFF(HOUR, '2025-05-12 00:00:01', '2025-05-12 23:59:59');  -- 23

坑3:字段类型是 DATETIME 但直接传字符串格式错误

sql

复制代码
-- 假设表中 create_time 是 DATETIME 类型
-- ❌ 错误比较(字符串格式不对)
SELECT DATEDIFF(create_time, '12-05-2025') FROM orders;  -- 可能 NULL

-- ✅ 正确:用标准格式字符串
SELECT DATEDIFF(create_time, '2025-05-12') FROM orders;  -- 正常计算

-- ✅ 或者直接用字段(最安全)
SELECT DATEDIFF(create_time, '2025-05-12') FROM orders;  -- create_time 会自动提取日期部分

刷题最佳实践

🎯 安全写法(推荐)

sql

复制代码
-- 1. 字段已经是日期/时间类型,直接使用
SELECT DATEDIFF(order_date, pay_date) FROM orders;

-- 2. 字符串日期统一转为标准格式
SELECT DATEDIFF('2025-05-12', '2025-05-10');

-- 3. 如果字段有时分秒,想按真实时间差(精确到24小时)用 TIMESTAMPDIFF
SELECT TIMESTAMPDIFF(DAY, '2025-05-12 00:00:01', '2025-05-13 00:00:00');  -- 0(不足24小时)
SELECT TIMESTAMPDIFF(HOUR, '2025-05-12 00:00:01', '2025-05-13 00:00:00');  -- 23

📝 xxx典型题目示例

sql

复制代码
-- 题目:计算用户下单到支付的天数
-- 表 orders: order_date (DATETIME), pay_date (DATETIME)

-- ✅ 直接用 DATEDIFF(自动忽略时分秒)
SELECT 
    order_id,
    DATEDIFF(pay_date, order_date) AS pay_days
FROM orders;

-- 如果题目要求"超过24小时才算1天",那就不能用 DATEDIFF
-- 改用 TIMESTAMPDIFF
SELECT 
    order_id,
    TIMESTAMPDIFF(DAY, order_date, pay_date) AS pay_days
FROM orders;

快速记忆

需求 用什么 示例
日历日期算差(忽略时间) DATEDIFF(date1, date2) DATEDIFF('2025-05-12 23:59', '2025-05-11 00:00')1
24小时时间差算 TIMESTAMPDIFF(DAY, dt1, dt2) TIMESTAMPDIFF(DAY, '2025-05-11 23:59', '2025-05-12 00:00')0
安全的日期字符串格式 'YYYY-MM-DD' '2025-05-12'(最稳妥)

一句话总结DATEDIFF 对格式宽容但有限制 ,只要 MySQL 能识别成有效日期(推荐 YYYY-MM-DD),无论带不带时分秒都能正确计算;非标准顺序(如 DD-MM-YYYY)会直接报错或返回 NULL。

相关推荐
Shely20172 小时前
数据库索引
数据库·mysql
我也不曾来过12 小时前
Mysql
数据库·mysql
雨辰AI3 小时前
面试题:人大金仓事务隔离级别、MVCC 机制详解(与MySQL差异对比)
数据库·后端·mysql·面试·政务
czlczl200209254 小时前
MySQL 基于 GTID 的 Binlog 主从同步机制
java·jvm·mysql
神仙别闹6 小时前
基于PHP+MySQL实现在线考试系统
开发语言·mysql·php
2501_921939267 小时前
MySQL(备份恢复、主从复制读写分离)
数据库·mysql
思麟呀8 小时前
MySQL基础CRUD语句
数据库·mysql
0xDevNull8 小时前
MySQL中的锁详解
mysql
Irene19918 小时前
触发器(Trigger) 是数据库中一种特殊的存储程序,它会在指定的表上发生特定事件(如 INSERT、UPDATE、DELETE)时自动执行
mysql