MySQL 单行函数


1. 函数的理解

1.1 什么是函数

C中有函数,Java中有方法,MySQL中就是函数

作用: 把经常使用的代码封装起来, 需要的时候直接调用即可

提高了代码效率

又提高了可维护性

SQL 中我们也可以使用函数对检索出来的数据进行函数操作,极大地提高 用户对数据库的管理效率

分类(按定义):

  1. 内置函数

系统内置的通用函数

  1. 自定义函数

根据自己的需要编写的


1.2 不同DBMS函数的差异

使用SQL常用 数据库软件(DBMS) 而非直接与语言打交道,而DBMS 之间的差异性很大,远大于同一个语言不同版本之间的差异

只有很少的函数是被 DBMS 同时支持的

比如,大多数 DBMS 使用(||)或者(+)来做拼接符,而在 MySQL 中的字符串拼接函数为concat()

大部分 DBMS 会有特定函数------采用 SQL 函数的代码可移植性很差


1.3 MySQL的内置函数及分类

  • 实现的功能角度可以分为数值函数、字符串函数、日期和时间函数、流程控制函数、加密与解密函数、获取MySQL信息函数、聚合函数等
  • 内置函数再分为两类: 单行函数聚合函数(或分组函数)

单行函数:

  1. 操作数据对象
  2. 接受参数返回一个结果
  3. 只对一行进行变换
  4. 每行返回一个结果
  5. 可以嵌套
  6. 参数可以是一列或一个值

2. 数值函数

2.1 基本函数

函数名 功能说明
ABS(x) 返回 x绝对值
SIGN(x) 返回 x符号 : 正数 → 1,负数 → -1,零 → 0
PI() 返回圆周率 π 的近似值(≈ 3.141592653589793)
CEIL(x) / CEILING(x) 返回大于或等于 x 的最小整数(向上取整
FLOOR(x) 返回小于或等于 x 的最大整数(向下取整
LEAST(e₁, e₂, e₃, ...) 返回参数列表中的最小值
GREATEST(e₁, e₂, e₃, ...) 返回参数列表中的最大值
MOD(x, y) 返回 x 除以 y余数 注意: • 多数数据库中结果符号与被除数 x 相同 • 若 y = 0,通常返回 NULL 或报错
RAND() 返回 [0, 1) 区间内的伪随机浮点数(含 0,不含 1)。无种子时每次调用结果不同
RAND(x) 返回 [0, 1) 区间内的伪随机浮点数,x 作为种子; 相同种子产生相同序列(确定性随机)(eg:rand(1)和rand(1)每次产生的随机数都相同,和rand(2)每次产生的都不同)
ROUND(x) x 四舍五入 到最接近的整数.5 向远离零方向舍入,即"银行家舍入"在部分系统中可能不同,需依具体数据库而定;多数 SQL 实现为"四舍五入")
ROUND(x, y) x 四舍五入小数点后 y ;若 y < 0,则对整数部分舍入(如 ROUND(123.456, -1) = 120
TRUNCATE(x, y) x 截断为小数点后 y (直接截断,不四舍五入) y 可为负数
SQRT(x) 返回 x平方根x < 0,返回 NULL(或报错,取决于系统)
  • 单行函数可嵌套
    eg:ROUND(TRUNCATE(x, y))

2.2 角度与弧度互换函数

函数 用法
RADIANS(x) 角度转化为弧度,其中,参数 x 为角度值
DEGREES(x) 弧度转化为角度,其中,参数 x 为弧度值

2.3 三角函数

函数名 原表"用法"描述 规范/准确解释 关键说明
SIN(x) 返回 x 的正弦值,其中参数 x 为弧度值 正弦函数:sin⁡(x)\sin(x)sin(x),输入为弧度 最常用三角函数;x 必须是弧度(如 30° 需先 RADIANS(30)
ASIN(x) 返回 x 的反正弦值......若 x ∉ [-1,1],返回 NULL 反正弦函数:arcsin⁡(x)\arcsin(x)arcsin(x),定义域 [−1,1][-1, 1][−1,1],值域 [−π2,π2][-\frac{\pi}{2}, \frac{\pi}{2}][−2π,2π] 输入超范围时行为因系统而异:• MySQL/PostgreSQL → NULL• SQL Server → 报错• Python (math.asin) → ValueError
COS(x) 返回 x 的余弦值,x 为弧度值 余弦函数:cos⁡(x)\cos(x)cos(x),输入为弧度 SIN 配合使用广泛(如单位圆、向量投影)
ACOS(x) 返回 x 的反余弦值......若 x ∉ [-1,1],返回 NULL 反余弦函数:arccos⁡(x)\arccos(x)arccos(x),定义域 [−1,1][-1, 1][−1,1],值域 [0,π][0, \pi][0,π] 同样要求输入 ∈ [-1,1];常用于计算夹角(如两点间方位角)
TAN(x) 返回 x 的正切值,x 为弧度值 正切函数:tan⁡(x)=sin⁡xcos⁡x\tan(x) = \frac{\sin x}{\cos x}tan(x)=cosxsinx,输入为弧度 在 x=π2+kπx = \frac{\pi}{2} + k\pix=2π+kπ 处无定义(趋于无穷);实际中可能返回极大值或报错
ATAN(x) 返回 x 的反正切值 反正切函数:arctan⁡(x)\arctan(x)arctan(x),定义域 R\mathbb{R}R,值域 (−π2,π2)(-\frac{\pi}{2}, \frac{\pi}{2})(−2π,2π) 安全函数:任意实数输入均有效;常用于由斜率求角度
ATAN2(m, n) 返回两个参数的反正切值 二参数反正切:atan2⁡(y,x)\operatorname{atan2}(y, x)atan2(y,x),返回点 (x,y)(x, y)(x,y) 与原点连线和 x 轴正方向的夹角(含象限信息) 重要补充 :• 参数顺序通常是 ATAN2(y, x) (注意:您表中写的是 ATAN2(m,n),但标准是 y 在前、x 在后)• 值域:(−π,π](-\pi, \pi](−π,π],可正确区分四个象限• 例如:ATAN2(1, 1) → π/4;ATAN2(-1, -1) → -3π/4(或 5π/4,依实现)
COT(x) 返回 x 的余切值,x 为弧度值 余切函数:cot⁡(x)=1tan⁡(x)=cos⁡xsin⁡x\cot(x) = \frac{1}{\tan(x)} = \frac{\cos x}{\sin x}cot(x)=tan(x)1=sinxcosx 注意:• 多数数据库不直接支持 COT() (如 MySQL 8.0+ 无内置,SQL Server 无,PostgreSQL 无)• 通常需手动实现:1 / TAN(x)COS(x)/SIN(x)• 在 x=kπx = k\pix=kπ 处无定义(分母为 0)

2.4 指数与对数

函数名 原表"用法"描述 规范解释与关键细节
POW(x, y) / POWER(x, y) 返回 x 的 y 次方 • 两者是同义函数(MySQL/SQL Server 中 POWER 更常用;PostgreSQL 支持 POWER^ 运算符) • 支持负指数:POW(2, -3) = 1/8 = 0.125 • 特殊情况: - x = 0, y > 00 - x = 0, y = 0通常返回 1 (数学争议,但多数系统定义为 1) - x = 0, y < 0报错或返回 NULL (除零错误) - x < 0, y 非整数 → 可能返回 NULL 或复数错误(如 POW(-2, 0.5) 是虚数,实数域无定义)
EXP(X) 返回 e 的 X 次方,e ≈ 2.71828... • 即自然指数函数:exp⁡(x)=ex\exp(x) = e^xexp(x)=ex• 定义域:全体实数 ℝ • 值域:(0,+∞)(0, +\infty)(0,+∞) • 与 LN(X) 互为反函数: EXP(LN(x)) = x(当 x>0x > 0x>0) LN(EXP(x)) = x(对所有实数 x 成立)
LN(X) / LOG(X) 返回以 e 为底的 X 的对数;X ≤ 0 时返回 NULL LN(X) 是标准写法(MySQL、PostgreSQL、Oracle) • LOG(X)MySQL 中等价于 LN(X) ;但在 SQL Server / Oracle 中,LOG(X) 默认是 LOG10(X) (重要差异!) • 定义域:X>0X > 0X>0;若 X≤0X \leq 0X≤0,行为: - MySQL/PostgreSQL → NULL - SQL Server → 报错(Invalid floating point operation) - Python (math.log) → ValueError
LOG10(X) 返回以 10 为底的 X 的对数;X ≤ 0 时返回 NULL • 常用在科学计算、dB 计算、数量级分析中 • 与 LOG(X) 区分:明确指定底数为 10 • 同样要求 X>0X > 0X>0,否则返回 NULL 或报错
LOG2(X) 返回以 2 为底的 X 的对数;X ≤ 0 时返回 NULL • 广泛用于计算机科学:比特位数、二叉树高度、信息熵等 • 例如:LOG2(8) = 3LOG2(1024) = 10• 支持情况: - MySQL 8.0+ ✔️ - PostgreSQL ✔️(log(2, x)log2(x)) - SQL Server ❌(需用 LOG(x)/LOG(2) 替代) - Oracle ✔️(LOG(2, x)

2.5 进制间的转换

函数名 原表"用法"描述 规范解释与重要说明
BIN(x) 返回 x 的二进制编码 • 将十进制整数 x 转换为二进制字符串(不含前缀) • 例如:BIN(10)'1010' • 仅支持非负整数;若 x < 0: - MySQL:返回带符号的补码形式(如 BIN(-1)'11111111111111111111111111111111',32位) - 其他系统(如 SQLite)可能报错或返回 NULL • 输出为字符串类型,非数值
HEX(x) 返回 x 的十六进制编码 • 将十进制整数 x 转为十六进制小写字符串(无 0x 前缀) • 例如:HEX(255)'ff'HEX(10)'a' • 同样要求 x 为整数;负数处理类似 BIN()(MySQL 返回补码) • 常用于颜色码、内存地址、哈希值显示等
OCT(x) 返回 x 的八进制编码 • 将十进制整数 x 转为八进制字符串(无前缀) • 例如:OCT(10)'12'(因 1010=1281010​=128​ ) • 应用较少,但在 Unix 权限(如 chmod 755)场景中有意义
CONV(x, f1, f2) 返回 f1 进制数变成 f2 进制数 • 通用进制转换函数: CONV(str_or_num, from_base, to_base) • 参数说明: - x:可为字符串或数字(若为字符串,需是合法 f1 进制表示) - f1:源进制(2--36) - f2:目标进制(2--36) • 示例: - CONV('A', 16, 10)'10'(十六进制 A → 十进制 10) - CONV(10, 10, 2)'1010'(十进制 10 → 二进制) - CONV('1010', 2, 16)'A' • 注意: - 若输入非法(如 CONV('G', 16, 10)),通常返回 NULL - 支持字母 A--Z 表示 10--35(大小写不敏感) - MySQL 特有函数;PostgreSQL/SQL Server 等需用自定义逻辑实现

3. 字符串函数

3.1 函数分类与逐项解析

3.1.1 基础信息获取类
函数 说明 关键细节
ASCII(s) 返回字符串 s 第一个字符的 ASCII 码 • 仅取首字符 • 非 ASCII 字符(如中文)返回其 UTF-8 编码首字节(MySQL 中) • 例:ASCII('A')=65, ASCII('中')=228(UTF-8 首字节)
CHAR_LENGTH(s) 返回字符串 s字符数(Unicode 字符个数) • 与 CHARACTER_LENGTH(s) 同义 • 区别于 LENGTH(s): - CHAR_LENGTH('café') = 4(4 个字符) - LENGTH('café') = 5(UTF-8 下 'é' 占 2 字节)
LENGTH(s) 返回字符串 s字节数 • 依赖字符集(utf8mb4 下中文占 4 字节) • 用于计算存储空间或网络传输大小

3.1.2 字符串拼接与构造类
函数 说明 补充说明
CONCAT(s1, s2, ..., sn) 连接多个字符串 • 若任一参数为 NULL,结果为 NULL• MySQL 中不可简写为 s1 + s2 + 是算术加法,字符串拼接必须用 CONCAT 或 `
CONCAT_WS(x, s1, s2, ...) 用分隔符 x 连接字符串 W ith S eparator • 自动跳过 NULL 参数(但保留空字符串 '') • 例:CONCAT_WS(',', 'a', NULL, 'c')'a,c'

3.1.3 字符串替换与修改类
函数 说明 注意事项
INSERT(str, idx, len, replacestr) idx 位置起,替换 len 个字符为 replacestr 位置从 1 开始 (MySQL 特性) • 若 idx > CHAR_LENGTH(str),则在末尾追加 • 若 len=0,相当于插入
REPLACE(str, a, b) str 中所有 a 替换为 b • 全局替换,非正则 • 例:REPLACE('hello world', 'l', 'X')'heXXo worXd'
UPPER(s) / UCASE(s) 转大写 • 两者等价;UCASE 是旧版兼容写法
LOWER(s) / LCASE(s) 转小写 • 同上

3.1.4 子字符串提取类
函数 说明
LEFT(str, n) 取最左 n 个字符
RIGHT(str, n) 取最右 n 个字符
SUBSTR(s, index, len) index 起取 len 个字符
LPAD(str, len, pad) 用字符串pad对str最左边进行填充,直到str的长度为len个字符
RPAD(str ,len, pad) 用字符串pad对str最右边进行填充,直到str的长度为len个字符

示例:
SUBSTR('abcdef', 2, 3)'bcd'
SUBSTR('abcdef', -3)'def'(负索引从右往左数)

  • LPAD/RPAD可用于左右对齐,用空格填充

3.1.5 空白字符处理类
函数 作用 差异点
LTRIM(s) 去左空格 仅去空格(' '),不去制表符 \t 等(除非用 TRIM(LEADING ' ' FROM s)
RTRIM(s) 去右空格 同上
TRIM(s) 去左右空格 标准 SQL 支持更灵活:TRIM(BOTH 'x' FROM s)
TRIM(s1 FROM s) 去掉 s 开头和结尾的 s1 • 例:TRIM('xy' FROM 'xyhelloxxy')'hellox'
TRIM(LEADING s1 FROM s) 仅去开头的 s1 MySQL 支持
TRIM(TRAILING s1 FROM s) 仅去结尾的 s1 MySQL 支持
SPACE(n) 返回 n 个空格组成的字符串 • 例:CONCAT('a', SPACE(3), 'b')'a b'

3.1.6 位置查找与比较类
函数 说明 注意事项
LOCATE(substr, str) 返回 substrstr首次出现的位置(从 1 开始) • 找不到返回 0 • 等价于 POSITION(substr IN str)INSTR(str, substr)
POSITION(substr IN str) LOCATE 标准 SQL 写法
INSTR(str, substr) LOCATE MySQL 特有(参数顺序相反!)→ INSTR(str, substr) vs LOCATE(substr, str)
ELT(m, s1, s2, ..., sn) 返回第 m 个参数 • 类似编程语言的"数组索引" • m < 1m > nNULL • 例:ELT(2, 'a','b','c')'b'
FIELD(s, s1, s2, ..., sn) 返回 s 在列表中第一次出现的位置 • 找不到返回 0 • 例:FIELD('mm', 'mm','hello','msm')1 • 常用于自定义排序(如 ORDER BY FIELD(id, 3,1,2)
FIND_IN_SET(s1, s2) 查找 s1 在以逗号分隔的字符串 s2 中的位置 s2 必须是 ',' 分隔的列表(不能含空格) • 例:FIND_IN_SET('hello', 'mm,hello,msm,amma')2 •不支持通配符,不适用于 JSON 数组

FIND_IN_SET 陷阱:

  • 'a''ab' 中找不到(必须完全匹配)
  • ' a '(带空格)在 'a,b' 中也找不到

3.1.7 其他实用函数
函数 说明 应用场景
REPEAT(str, n) 重复 str n • 生成固定长度填充:REPEAT('0', 5-CHAR_LENGTH(id)) + id → 补零
STRCMP(s1, s2) 比较两个字符串的 ASCII 值大小 • 返回:-1(s1 < s2)、0(相等)、1(s1 > s2) • 可用于 ORDER BY STRCMP(col, 'target') 实现"目标值置顶"
NULLIF(value1, value2) value1 = value2 则返回 NULL,否则返回 value1 • 防止除零:SELECT num / NULLIF(denom, 0) • 等价于 CASE WHEN value1 = value2 THEN NULL ELSE value1 END
REVERSE(s) 返回s反转后的字符串 -

3.2 关键注意事项

注意:MySQL 中,字符串的位置是从 1 开始的。


3.3 典型应用场景举例

3.3.1 补零 ID 格式化
sql 复制代码
-- 将数字 ID 补成 6 位:000123
SELECT LPAD(id, 6, '0') AS formatted_id FROM users;
-- 或用 REPEAT:
SELECT REPEAT('0', 6 - CHAR_LENGTH(id)) + id AS formatted_id;
3.3.2 自定义排序(按指定顺序)
sql 复制代码
SELECT * FROM products 
ORDER BY FIELD(category, 'Electronics', 'Books', 'Clothing');
3.3.3 安全除法(防除零)
sql 复制代码
SELECT amount / NULLIF(quantity, 0) AS unit_price FROM sales;
3.3.4 提取文件扩展名
sql 复制代码
-- 假设 filename = 'report.pdf'
SELECT SUBSTRING_INDEX(filename, '.', -1) AS ext;  -- 'pdf'
-- (注:`SUBSTRING_INDEX` 未在表中列出,但常用)

4. 日期和时间函数

4.1 获取日期、时间

函数(写法) 用法 规范解释与重要说明
CURDATE() , CURRENT_DATE() 返回当前日期,只包含年、月、日 • 返回 DATE 类型值(格式如 '2024-06-15') • 两者完全等价(CURRENT_DATE 是 SQL 标准写法,CURDATE 是 MySQL 特有别名) • 不带时区信息,基于服务器系统时间
CURTIME() , CURRENT_TIME() 返回当前时间,只包含时、分、秒 • 返回 TIME 类型值(格式如 '14:30:45') • 同样两者等价;CURRENT_TIME 是标准,CURTIME 是 MySQL 别名 • 可选精度:CURTIME(6)'14:30:45.123456'(微秒级)
NOW() SYSDATE() CURRENT_TIMESTAMP() LOCALTIME() LOCALTIMESTAMP() 返回当前系统日期和时间 这些函数看似相同,但行为有关键差异: NOW(): - 返回 语句开始执行时的时间(固定值) - 在同一语句内多次调用结果相同(用于事务一致性) SYSDATE(): - 返回 函数被调用时的实时时间(动态值) - 同一语句内多次调用可能不同(如 SELECT SYSDATE(), SLEEP(2), SYSDATE()CURRENT_TIMESTAMP(), LOCALTIME(), LOCALTIMESTAMP(): - 在 MySQL 中 等价于 NOW()(即语句开始时间) - LOCAL* 是 SQL 标准写法,兼容性更好 示例: sql<br>SELECT NOW(), SYSDATE(), SLEEP(2), NOW(), SYSDATE();<br>-- 结果:t, t+2s, t, t+2s (t 为语句开始时间)<br>
UTC_DATE() 返回 UTC(世界标准时间)日期 • 返回当前 UTC 日期(DATE 类型) • 不受服务器时区影响 • 例:服务器在东八区(北京时间),CURDATE() = '2024-06-15'UTC_DATE() 可能是 '2024-06-14'(若此时为 00:30 北京时间)
UTC_TIME() 返回 UTC(世界标准时间)时间 • 返回当前 UTC 时间(TIME 类型) • 与 UTC_DATE() 配合可得完整 UTC 时间戳: CONCAT(UTC_DATE(), ' ', UTC_TIME())
  • UTC时间与北京时间差8小时

4.2 日期与时间戳的转换

函数 用法描述 规范解释与关键细节
UNIX_TIMESTAMP() 以 UNIX 时间戳 的形式返回当前时间 。 示例:SELECT UNIX_TIMESTAMP() → 1634348884 • 返回 自 1970-01-01 00:00:00 UTC 起的秒数(整数类型) • 注意:MySQL 中默认返回 秒级(非毫秒);若需微秒级,可用 UNIX_TIMESTAMP() * 1000 + MICROSECOND(NOW(6)) / 1000 • 时区影响: - 函数返回的是 UTC 时间对应的秒数,与服务器本地时区无关 - 即使服务器设为 +8:00UNIX_TIMESTAMP() 仍基于 UTC 计算 • 示例: UNIX_TIMESTAMP('2021-10-15 12:00:00')1634270400(该时间点的 UTC 秒数)
UNIX_TIMESTAMP(date) 将时间 date 以 UNIX 时间戳形式返回 • 参数 date 可为: - 字符串(如 '2021-10-15', '2021-10-15 12:00:00') - DATE / DATETIME / TIMESTAMP 类型值 • 解析规则: - 若只传日期(无时间),默认视为 UTC 时间的 00:00:00 → UNIX_TIMESTAMP('2021-10-15') = 1634256000(即 2021-10-15 00:00:00 UTC) - 若传带时区的字符串(如 '2021-10-15 12:00:00+08:00'),MySQL 不支持直接解析时区偏移!会当作本地时间处理(依赖会话时区)→ 易出错! • 安全做法:统一使用 UTC 时间字符串输入
FROM_UNIXTIME(timestamp) 将 UNIX 时间戳转换为普通格式的时间 • 输入:整数(秒级 UNIX 时间戳) • 输出:DATETIME 类型(格式如 '2021-10-15 12:00:00') • 时区行为: - 结果基于会话时区(@@session.time_zone)!

4.3 获取月份、星期、星期数、天数等函数

函数 用法 解释 + 关键细节
YEAR(date) / MONTH(date) / DAY(date) 返回具体的日期值 • 提取年、月、日 的数值(整数) • 例:YEAR('2024-06-15') = 2024MONTH('2024-06-15') = 6DAY('2024-06-15') = 15 • 等价于 YEAR(), MONTH(), DAYOFMONTH()(注意:DAY() = DAYOFMONTH()
HOUR(time) / MINUTE(time) / SECOND(time) 返回具体的时间值 • 提取时、分、秒 的数值 • 例:HOUR('14:30:45') = 14 • 支持 DATETIME/TIMESTAMP 类型输入
MONTHNAME(date) 返回月份:January, ... • 返回英文全称(受 lc_time_names 系统变量影响) • 可通过 SET lc_time_names = 'zh_CN' 改为中文(需对应语言包) • 例:MONTHNAME('2024-06-15') = 'June'
DAYNAME(date) 返回星期几:MONDAY, TUESDAY...SUNDAY • 返回英文全称大写(如 'SATURDAY') • 同样受 lc_time_names 影响,可本地化 • 注意:不是数字!是字符串
WEEKDAY(date) 返回周几,注意:周1是0,周2是1,... 周日是6 MySQL 特有规则: • WEEKDAY():周一 = 0,周日 = 6 • 例:WEEKDAY('2024-06-15')(周六)→ 5 • 与 DAYOFWEEK() 完全相反!极易混淆
QUARTER(date) 返回日期对应的季度,范围为 1~4 • 1月--3月 → 1;4月--6月 → 2;7月--9月 → 3;10月--12月 → 4 • 例:QUARTER('2024-05-20') = 2
WEEK(date), WEEKOFYEAR(date) 返回一年中的第几周 • 两者等价(WEEKOFYEAR 是别名) • 但 周的定义取决于模式(mode)!默认模式 0: - 第一周是包含 1 月 1 日的那一周 - 周日为每周第一天(与 WEEKDAY 冲突!) • 可指定模式:WEEK(date, mode),常见: - mode=1:周一为每周第一天,且第一周必须有 4 天以上在本年 → ISO 标准周 - mode=3:同上,但返回 0~53 • 例: WEEK('2024-01-01')1(默认模式) WEEK('2024-01-01', 1)1(ISO 周) WEEK('2023-12-31', 1)52(2023 年第 52 周)
DAYOFYEAR(date) 返回日期是一年中的第几天 • 范围 1~366(闰年) • 例:DAYOFYEAR('2024-01-01') = 1DAYOFYEAR('2024-12-31') = 366
DAYOFMONTH(date) 返回日期位于所在月份的第几天 • 即 DAY(date) 的正式名称 • 例:DAYOFMONTH('2024-06-15') = 15
DAYOFWEEK(date) 返回周几 注意: 周日是1,周一2,... 周六是7 这是另一套编号体系: • DAYOFWEEK():周日 = 1,周一 = 2,...,周六 = 7 • 与 WEEKDAY() 完全相反! • 例:DAYOFWEEK('2024-06-15')(周六)→ 7 • 这是 SQL 标准行为(PostgreSQL/SQL Server 也如此)

4.4 日期的操作函数

函数 用法
EXTRACT(type FROM date) 返回指定日期中的特定部分,type指定返回的值
type的取值与含义:
type 取值 含义 示例(输入 '2024-06-15 14:30:45.123456' 注意事项
MICROSECOND 毫秒数(0~999999) 123456 精度最高
SECOND 秒数(0~59) 45 ---
MINUTE 分钟数(0~59) 30 ---
HOUR 小时数(0~23) 14 ---
DAY 月内天数(1~31) 15 = DAYOFMONTH()
WEEK 年内第几周(默认 mode 0) 24 行为依赖 default_week_format,建议显式用 WEEK()
MONTH 月份(1~12) 6 = MONTH()
QUARTER 季度(1~4) 2 = QUARTER()
YEAR 年份(4位) 2024 = YEAR()
SECOND_MICROSECOND 秒 + 毫秒(如 45.123456 45.123456 MySQL 8.0+ 返回 DECIMAL;旧版返回字符串
MINUTE_MICROSECOND 分 + 毫秒(如 30.123456 30.123456 同上
MINUTE_SECOND 分 + 秒(如 30.45 30.45 注意:不是 3045!是小数形式
HOUR_MICROSECOND 时 + 毫秒(如 14.000123 14.000123 ---
HOUR_SECOND 时 + 秒(如 14.45 14.45 ---
HOUR_MINUTE 时 + 分(如 14.30 14.30 易错:不是 '14:30' 字符串(MySQL 8.0+ 是 DECIMAL)
DAY_MICROSECOND 天 + 毫秒(如 15.000123 15.000123 ---
DAY_SECOND 天 + 秒(如 15.45 15.45 ---
DAY_MINUTE 天 + 分(如 15.30 15.30 ---
DAY_HOUR 天 + 小时(如 15.14 15.14 ---
YEAR_MONTH 年 + 月(如 2024.06 2024.06 实际返回 2024.06(DECIMAL),可用于按年月分组

4.5 时间和秒钟转换的函数

函数 原表"用法"描述 规范解释 + 关键补充
TIME_TO_SEC(time) time 转化为秒并返回结果值。 公式:小时 × 3600 + 分钟 × 60 + 秒 时间 转 秒 • 输入类型:TIME, DATETIME, TIMESTAMP 或字符串(如 '14:30:45', '2 14:30:45') • 支持"天数"前缀!例如: TIME_TO_SEC('2 14:30:45')2×86400 + 14×3600 + 30×60 + 45 = 225045 • 返回值类型:BIGINT(整数) • 注意:若输入为负时间(如 '-01:30:00'),返回负值(-5400) • 对 DATETIME 类型:仅提取时间部分,忽略日期! 例:TIME_TO_SEC('2024-06-15 14:30:45') = 52245(=14×3600+30×60+45)
SEC_TO_TIME(seconds) seconds 描述转化为包含小时、分钟和秒的时间 秒 转 时间 • 输入:整数(可正可负) • 输出类型:TIME(格式如 '14:30:45''-01:30:00') • 支持大数值(最大约 838:59:59,即 838 小时上限) • 重要限制: MySQL 的 TIME 类型范围是 -838:59:59838:59:59 → 若 seconds > 838*3600+59*60+59 = 3020399,会截断或报错(取决于 SQL 模式) • 示例: SEC_TO_TIME(52245)'14:30:45' SEC_TO_TIME(-5400)'-01:30:00'

4.6 计算日期和时间的函数

4.6.1 第一组
函数 用法
DATE_ADD(datetime, INTERVAL expr type)ADDDATE(date,INTERVAL expr type) 返回与给定日期时间相差INTERVAL时间段的日期时间
DATE_SUB(date,INTERVAL expr type)SUBDATE(date,INTERVAL expr type) 返回与date相差INTERVAL时间间隔的日期
  • 注: add加,sub减,但仅用add通过正负也可以实现加减

type 的取值:

unit 取值 含义 示例 注意事项
HOUR 小时 INTERVAL 2 HOUR 支持负数
MINUTE 分钟 INTERVAL 30 MINUTE ---
SECOND INTERVAL 45 SECOND ---
YEAR INTERVAL 5 YEAR 跳过闰年问题(2020+5=2025)
MONTH INTERVAL 1 MONTH 最常用也最易错:见上文智能进位
DAY INTERVAL 7 DAY 等价于 WEEK?不!7 DAY = 1周,但 WEEK 单位是 7 天
YEAR_MONTH 年+月 INTERVAL 2 YEAR 3 MONTH 支持组合(见下文)
DAY_HOUR 日+小时 INTERVAL 1 DAY 2 HOUR 支持多单位组合!
DAY_MINUTE 日+分 INTERVAL 1 DAY 30 MINUTE ---
DAY_SECOND 日+秒 INTERVAL 1 DAY 10 SECOND ---
HOUR_MINUTE 时+分 INTERVAL 2 HOUR 15 MINUTE ---
HOUR_SECOND 时+秒 INTERVAL 1 HOUR 30 SECOND ---
MINUTE_SECOND 分+秒 INTERVAL 5 MINUTE 45 SECOND ---
4.6.2 第二组
函数 用法 本质 实战建议
ADDTIME(time1, time2) time1 + time2 时间相加(非日期) 适合纯时间累加(如班次时长)
SUBTIME(time1, time2) time1 - time2 时间相减 注意:结果可为负('-01:30:00'
DATEDIFF(date1, date2) date1 - date2(天数) 仅比较日期部分,忽略时间 快速计算"相差几天",如会员到期提醒
TIMEDIFF(time1, time2) time1 - time2(时间差) 返回 TIME 类型(如 '02:15:30' 计算会话时长、响应时间
FROM_DAYS(N) 0000-01-01 起第 N 天的日期 N=10000-01-01N=7380002020-01-01 用于日志序列号转日期(罕见)
TO_DAYS(date) 返回 date 距离 0000-01-01 的天数 FROM_DAYS 互为反函数 性能优化:用 TO_DAYS 做范围查询(但现代索引更推荐 DATE 直接比较)
LAST_DAY(date) 返回 date 所在月份的最后一天 LAST_DAY('2024-06-15') = '2024-06-30' 生成报表截止日、财务月结日
MAKEDATE(year, n) n 天的日期(n=1year-01-01 MAKEDATE(2024, 172) = '2024-06-20' 用于按"年内第几天"生成日期
MAKETIME(hour, min, sec) 组合时间 MAKETIME(14,30,45) = '14:30:45' 构造动态时间值
PERIOD_ADD(time, n) time(格式 YYMMYYYYMM)加 n 个月 PERIOD_ADD(202406, 3) = 202409 用于金融/账期管理(如 202406 表示2024年6月)

4.7 日期的格式化与解析

  • 日期的显式格式化
函数 输入类型 输出类型 核心用途
DATE_FORMAT(date, fmt) DATE / DATETIME / TIMESTAMP VARCHAR 按照字符串fmt格式化日期date值 data->str
TIME_FORMAT(time, fmt) TIME / DATETIME VARCHAR 按照字符串fmt格式化时间time值 time->str
GET_FORMAT(date_type, format_type) 字符串参数 VARCHAR 返回日期字符串的显示格式 ->str 按指定格式转换
STR_TO_DATE(str, fmt) VARCHAR + 格式模板 DATE / DATETIME 按照字符串fmt对str进行解析,解析为一个日期 str->date
上述非GET_FORMAT 函数中fmt参数常用的格式符:
格式符 正确含义 示例(输入 2024-06-15 14:30:45
%Y 4位年份 2024
%y 2位年份 24
%M 全称月份英文(January) June
%b 缩写月份(Jan, Feb) Jun
%m 2位数字月份 06
%c 1位数字月份(1~12) 6
%D 英文后缀日(1st, 2nd) 15th
%d 2位数字日 15
%e 1位数字日(1~31) 15
%H 24小时制小时(00~23) 14
%h%I 12小时制小时(01~12) 02
%k 24小时制小时(0~23,无前导零) 14
%l 12小时制小时(1~12,无前导零) 2
%i 2位分钟 30
%s 2位秒数 45
%f 微秒(6位) 000000(若无微秒则补零)
%W 全称星期名(Sunday) Saturday
%a 缩写星期名(Sun) Sat
%w 数字星期(0=周日, 6=周六) 6
%j 年内第几天(001~366) 167
%U 年内第几周(周日为每周第一天) 24
%u 年内第几周(周一为每周第一天,ISO标准) 24
%T HH:MM:SS(24小时) 14:30:45
%r hh:mm:ss AM/PM(12小时) 02:30:45 PM
%p AM 或 PM PM
GET_FORMAT函数中date_type和format_type参数取值如下:
日期类型 格式化类型 返回的格式化字符串
DATE USA %m.%d.%Y
DATE JIS %Y-%m-%d
DATE ISO %Y-%m-%d
DATE EUR %d.%m.%Y
DATE INTERNAL %Y%m%d
TIME USA %h:%i:%s %p
TIME JIS %H:%i:%s
TIME ISO %H:%i:%s
TIME EUR %H:%i:%s
TIME INTERNAL %H%i%s
DATETIME USA %Y-%m-%d %H:%i:%s
DATETIME JIS %Y-%m-%d %H:%i:%s
DATETIME ISO %Y-%m-%d %H:%i:%s
DATETIME EUR %Y-%m-%d %H:%i:%s
DATETIME INTERNAL %Y%m%d%H%i%s

5. 流程控制函数

  • 根据不同的条件,执行不同的处理流程,可以在SQL语句中实现不同的条件选择
  • 主要包括IF()、IFNULL()和CASE()函数
函数 用法
IF(value, value1, value2) 如果 value 的值为 TRUE,返回 value1,否则返回 value2
IFNULL(value1, value2) 如果 value1 不为 NULL,返回 value1,否则返回 value2
CASE WHEN 条件1 THEN 结果1 WHEN 条件2 THEN 结果2 ... [ELSE 结果n] END 相当于 Java 的 if...else if...else...
CASE expr WHEN 常量值1 THEN 值1 WHEN 常量值1 THEN 值1 ... [ELSE 值n] END 相当于 Java 的 switch...case...
  • IF(value, value1, value2)
sql 复制代码
mysql> SELECT 
	->   last_name,
	->   salary,
	->   IF(salary >= 6000,'高工资','低工资') 'details'
    -> FROM employees;
+-------------+----------+---------+
| last_name   | salary   | details |
+-------------+----------+---------+
| King        | 24000.00 | 高工资   |
| Kochhar     | 17000.00 | 高工资   |
| De Haan     | 17000.00 | 高工资   |
| Hunold      |  9000.00 | 高工资   |
| Ernst       |  6000.00 | 高工资   |
| Austin      |  4800.00 | 低工资   |
| Pataballa   |  4800.00 | 低工资   |
| ...         |      ... | ...     |
+-------------+----------+---------+
(省略100条记录)
107 rows in set (0.01 sec)
  • IFNULL(value1, value2)
sql 复制代码
mysql> SELECT
    ->  last_name,
    ->  commission_pct,
    ->  IFNULL(commission_pct,0) 'details'
    -> FROM
    ->  employees;
+-------------+----------------+---------+
| last_name   | commission_pct | details |
+-------------+----------------+---------+
| King        |           NULL |    0.00 |
| Kochhar     |           NULL |    0.00 |
| De Haan     |           NULL |    0.00 |
| Hunold      |           NULL |    0.00 |
| Ernst       |           NULL |    0.00 |
| ...         |            ... |     ... |
| Hutton      |           0.25 |    0.25 |
| Taylor      |           0.20 |    0.20 |
| Livingston  |           0.20 |    0.20 |
| Grant       |           0.15 |    0.15 |
| Johnson     |           0.10 |    0.10 |
| ...         |            ... |     ... |
| Baer        |           NULL |    0.00 |
| Higgins     |           NULL |    0.00 |
| Gietz       |           NULL |    0.00 |
+-------------+----------------+---------+
(...为省略记录)
107 rows in set (0.00 sec)
  • CASE WHEN 条件1 THEN 结果1 WHEN 条件2 THEN 结果2 ... [ELSE 结果n] END
sql 复制代码
mysql> SELECT
    ->  last_name,
    ->  CASE
    ->          WHEN salary >= 10000 THEN
    ->          '高工资'
    ->          WHEN salary >= 5000 THEN
    ->          '中工资'
    ->          ELSE '低工资'
    ->  END 'details'
    -> FROM
    ->  employees;
+-------------+---------+
| last_name   | details |
+-------------+---------+
| King        | 高工资   |
| Kochhar     | 高工资   |
| De Haan     | 高工资   |
| Hunold      | 中工资   |
| Ernst       | 中工资   |
| Austin      | 低工资   |
| ...         | ...     |
+-------------+---------+
(...为省略记录)
107 rows in set (0.00 sec)

注:若没有else,则else的内容输出NULL

  • CASE expr WHEN 常量值1 THEN 值1 WHEN 常量值1 THEN 值1 ... [ELSE 值n] END
sql 复制代码
mysql> SELECT
    ->  employee_id,
    ->  last_name,
    ->  department_id,
    ->  CASE department_id
    ->          WHEN 10 THEN salary * 1.1
    ->          WHEN 20 THEN salary * 1.2
    ->          WHEN 30 THEN salary * 1.3
    ->          ELSE salary * 1.4
    ->  END 'details'
    -> FROM employees;
+-------------+-------------+---------------+----------+
| employee_id | last_name   | department_id | details  |
+-------------+-------------+---------------+----------+
|         100 | King        |            90 | 33600.00 |
|         101 | Kochhar     |            90 | 23800.00 |
|         102 | De Haan     |            90 | 23800.00 |
|         103 | Hunold      |            60 | 12600.00 |
|         104 | Ernst       |            60 |  8400.00 |
|         105 | Austin      |            60 |  6720.00 |
|         106 | Pataballa   |            60 |  6720.00 |
|          ...| ...         |           ... |      ... |
+-------------+-------------+---------------+----------+
(...为省略记录)
107 rows in set (0.00 sec)

Q&A:

Q:为什么没有循环?

A:sql自带循环,不用写


6. 加密与解密函数

  • 加密与解密函数主要用于对数据库中的数据进行加密和解密处理,以防止数据被他人窃取
  • 这些函数在保证数据库安全时非常有用
函数 用法
PASSWORD(str) 返回字符串 str 的加密版本,41 位长的字符串 加密结果 不可逆 ,常用于用户的密码加密 注意:8.0起不再推荐使用,使用会报错
MD5(str) 不可逆 返回字符串 str 的 MD5 加密后的值,也是一种加密方式 若参数为 NULL,则返回 NULL
SHA(str) 不可逆 从原明文密码 str 计算并返回加密后的密码字符串;当参数为 NULL 时,返回 NULL SHA 加密算法比 MD5 更加安全
ENCODE(value, password_seed) 返回使用 password_seed 作为加密密钥对 value 进行加密 的结果 注意:8.0起不再推荐使用,使用会报错
DECODE(value, password_seed) 返回使用 password_seed 作为解密密钥对 value 进行解密 的结果 注意:8.0起不再推荐使用,使用会报错
  • ENCODE(value,password_seed)函数与DECODE(value,password_seed)函数互为反函数
  • 加密不可逆,匹配可匹配暗文是否相同
    防破解

7. MySQL信息函数

  • MySQL中内置了一些可以查询MySQL信息的函数
  • 作用: 帮助数据库开发或运维人员更好地对数据库进行维护工作
函数 用法
VERSION() 返回当前 MySQL 的版本号
CONNECTION_ID() 返回当前 MySQL 服务器的连接数 (即当前会话的连接 ID)
DATABASE(), SCHEMA() 返回 MySQL 命令行当前所在的数据库名 (二者等价,SCHEMA()DATABASE() 的同义词)
USER(), CURRENT_USER(), SYSTEM_USER(), SESSION_USER() 返回当前 连接 MySQL 的用户名 ,返回结果格式为 "主机名@用户名"
CHARSET(value) 返回字符串 value 所使用的字符集
COLLATION(value) 返回字符串 value 所使用的校对规则(排序规则)

8. 其他函数

MySQL中有些函数无法 对其进行具体的分类

但是这些函数在MySQL的开发和运维过程中也是不容忽视

函数 用法
FORMAT(value, n) 返回对数字 value 进行格式化后的结果数据 n 表示 四舍五入 后保留到小数点后 n 位 注:如果n的值小于或者等于0,则只保留整数部分
CONV(value, from, to) value 的值在不同进制之间进行转换 (如十进制 ↔ 二进制 ↔ 十六进制等) fromto 为进制基数(2--36)
INET_ATON(ipvalue) 以点分隔的 IP 地址 (如 '192.168.1.1')转化为一个无符号整数(32 位)
INET_NTOA(value) 将数字形式的 IP 地址(整数) 转化为以点分隔的 IP 地址字符串 (如 3232235777'192.168.1.1')。
BENCHMARK(n, expr) 表达式 expr 重复执行 n ,用于测试 MySQL 处理该表达式所耗费的时间(常用于性能调优或基准测试)。
CONVERT(value USING char_code) value 所使用的字符编码修改为指定的 char_code (如 utf8mb4, latin1),实现字符集转换。
  • 以"192.168.1.100"为例,计算方式为192乘以256的3次方,加上168乘以256的2次方,加上1乘以256,再加上100
sql 复制代码
mysql> SELECT BENCHMARK(1, MD5('mysql'));
+----------------------------+
| BENCHMARK(1, MD5('mysql')) |
+----------------------------+
|                          0 |
+----------------------------+
1 row in set (0.00 sec)

mysql> SELECT BENCHMARK(1000000, MD5('mysql'));
+----------------------------------+
| BENCHMARK(1000000, MD5('mysql')) |
+----------------------------------+
|                                0 |
+----------------------------------+
1 row in set (0.94 sec)
  • 注意看上面的时间

相关推荐
字节跳动开源2 小时前
Viking AI 搜索 CLI 正式发布:会说话,就能做搜索推荐
数据库·人工智能·开源
TechWJ3 小时前
数据库在公司内网,出差路上想查数据怎么办?
服务器·数据库·mariadb
我是一颗柠檬3 小时前
【MySQL全面教学】MySQL事务与ACID Day9(2026年)
数据库·后端·mysql
橙子圆1233 小时前
Redis知识9之集群
数据库·redis·缓存
BlackHeart12033 小时前
【SQL】Oracle中序列(Sequence)作为默认值引发的ORA-00979
数据库·sql·oracle
bug菌4 小时前
【SpringBoot 3.x 第254节】夯爆了,数据库访问性能优化实战详解!
数据库·spring boot·后端
xxl大卡4 小时前
MySQL的执行流程
数据库·mysql
chicheese4 小时前
MySQL优化实践:选错JOIN 驱动表,性能相差几十倍
数据库·mysql
锋行天下4 小时前
一句mysql复杂查询搞崩一个壮汉
后端·mysql·go