SQL 自学笔记(6)单行函数
单行函数
本文笔记根据【b站 尚硅谷-宋红康 MySQL 课程】整理。笔记和代码存储在我的 GitHub 库中 github.com/isKage/sql-notes。
不同的数据库管理系统 DBMS 的函数使用差异极大,SQL 语言函数的可移植性很差。下面我们介绍的是 SQL 语言的内置函数。
MySQL 提供的内置函数包括单行函数和聚合函数,这章讲解单行函数。
单行函数:对行数据进行操作;输入参数,返回结果;对每行进行操作。
1 数值函数
1.1 基本数值函数
ABS(x):返回 x 的绝对值SIGN(x):返回 x 的符号,正数返回 1 ,负数返回 -1 , 0 返回 0PI():返回圆周率的值CEIL(x), CEILING(x):返回大于或等于 x 的最小整数FLOOR(x):返回小于或等于 x 的最大整数LEAST(x1, x2, x3, ...):返回列表中的最小值GREATEST(x1, x2, x3, ...):返回列表中的最大值MOD(x, y):返回 x 除以 y 后的余数RAND():返回 0-1 的随机值RAND(x):返回 0-1 的随机值,其中 x 的值用作种子值,相同的X值会产生相同的随机数ROUND(x):返回一个对 x 的值进行四舍五入后,最接近于 x 的整数ROUND(x, y):返回一个对 x 的值进行四舍五入后最接近 x 的值,并保留到小数点后面 y 位TRUNCATE(x, y):返回数字 x 截断为 y 位小数的结果SQRT(x):返回 x 的平方根,当 x 的值为负数时,返回NULLRADIANS(x):将角度转化为弧度,其中参数 x 为角度值DEGREES(x):将弧度转化为角度,其中参数 x 为弧度值
1 | SELECT ABS(-10), -- 10 |
1.2 三角函数
以下 x 均为弧度值
SIN(x):正弦值ASIN(x):反正弦值,即获取正弦为 x 的弧度,如果 x 的值不在 [-1, 1] ,则返回 NULLCOS(x):余弦值ACOS(x):返回 x 的反余弦值,即获取余弦为 x 的弧度,如果 x 的值不在 [-1, 1] ,则返回 NULLTAN(x):正切值ATAN(x):返回 x。的反正切值,即获取正切值为 x 的弧度ATAN2(m,n):返回点 (m, n) 到 (0, 0) 的连线构成的角度的弧度值COT(x):余切值
反三角函数返回的就是角度的弧度值,可以方便的得到角度大小
ATAN2(m, n) 函数返回 (m, n) 到 (0, 0) 的连线构成的角度的弧度值。如果使用 ATAN(x) 则会出现报错,例如当 时,即求点 (1, 0) 到 (0, 0) 的连线构成的角度的弧度值
1 | SELECT SIN(RADIANS(30)), -- sin(π/6) = 0.5 |
1.3 指数与对数
POW(x, y), POWER(x, y):返回 x 的 y 次方EXP(X):返回 e 的 x 次方,e 为自然对数LN(x), LOG(x):返回以 e 为底的 x 的对数,当 x 小于等于 0 时,返回 NULLLOG10(x):返回以 10 为底的 x 的对数,当 x 小于等于 0 时,返回 NULLLOG2(x):返回以 2 为底的 x 的对数,当 x 小于等于 0 时,返回 NULL
1 | SELECT POW(2, 5), -- 2^5 = 32 |
1.4 进制转换
BIN(x):返回 x 的二进制编码HEX(x):返回 x 的十六进制编码OCT(x):返回 x 的八进制编码CONV(x, f1, f2):返回 x 从 f1 进制数变成 f2 进制数
1 | SELECT BIN(1), -- 1 |
2 字符串函数
MySQL 中,字符串的位置是从 1 开始计数
-
ASCII(s):返回字符串 s 中的第一个字符的 ASCII 码 -
CHAR_LENGTH(s):返回字符串s的字符数,作用与CHARACTER_LENGTH(s)相同 -
LENGTH(s):返回字符串s的字节数(与字符集有关) -
CONCAT(s1, s2, ..., sn):将s1, s2, ..., sn连接为一个字符串 -
CONCAT_WS(x, s1, s2, ..., sn):用分隔符x连接s1, s2, ..., sn(每个字符串间插入x) -
INSERT(str, idx, len, replacestr):从字符串str的idx位置开始,替换len个字符为replacestr -
REPLACE(str, a, b):将字符串str中所有子串a替换为b -
UPPER(s)或UCASE(s):将字符串s全部转为大写 -
LOWER(s)或LCASE(s):将字符串s全部转为小写 -
LEFT(str, n):返回字符串str最左侧的n个字符 -
RIGHT(str, n):返回字符串str最右侧的n个字符 -
LPAD(str, len, pad):用pad从左侧填充str,直到总长度为len -
RPAD(str, len, pad):用pad从右侧填充str,直到总长度为len -
LTRIM(s):去掉字符串s左侧的空格 -
RTRIM(s):去掉字符串s右侧的空格 -
TRIM(s):去掉字符串s开头和结尾的空格 -
TRIM(s1 FROM s):去掉字符串s开头和结尾的s1 -
TRIM(LEADING s1 FROM s):去掉字符串s开头的s1 -
TRIM(TRAILING s1 FROM s):去掉字符串s结尾的s1 -
REPEAT(str, n):返回str重复n次的结果 -
SPACE(n):返回由n个空格组成的字符串 -
STRCMP(s1, s2):比较字符串s1和s2的 ASCII 码值大小 -
SUBSTR(s, index, len):从s的index位置截取len个字符,作用同SUBSTRING(s, n, len)和MID(s, n, len) -
LOCATE(substr, str):返回substr在str中首次出现的位置,作用同POSITION(substr IN str)和INSTR(str, substr)(未找到返回0) -
ELT(m, s1, s2, ..., sn):返回第m个字符串(如m=1返回s1) -
FIELD(s, s1, s2, ..., sn):返回s在列表s1, s2, ..., sn中第一次出现的位置 -
FIND_IN_SET(s1, s2):返回s1在逗号分隔的字符串s2中的位置 -
REVERSE(s):返回s反转后的字符串 -
NULLIF(value1, value2):若value1与value2相等则返回NULL,否则返回value1
例:FIND_IN_SET(s1, s2) 函数
1 | SELECT FIELD('mm', 'hello', 'msm', 'amma'), -- 0 : 因为 mm 没有出现在字符串列表中 |
FIND_IN_SET(s1, s2):返回s1在逗号分隔的字符串s2中的位置。s2是里的元素只能以逗号为间隔
1 | SELECT FIND_IN_SET('mm', 'hello,mm,amma'), -- 2 : 出现在第 2 个,从 1 开始计数 |
例:NULLIF() 函数
1 | SELECT NULLIF('mysql', 'mysql'), -- 相同返回 NULL |
3 日期和时间函数
3.1 获取日期和时间
-
CURDATE(), CURRENT_DATE():返回当前日期,只包含年、月、日 -
CURTIME(), CURRENT_TIME():返回当前时间,只包含时、分、秒 -
NOW()SYSDATE()CURRENT_TIMESTAMP()LOCALTIME()LOCALTIMESTAMP():返回当前系统日期和时间 -
UTC_DATE():返回 UTC(世界标准时间)日期 -
UTC_TIME():返回UTC(世界标准时间)时间
1 | SELECT CURDATE(), -- 2025-02-10 |
3.2 日期与时间戳的转换
UNIX_TIMESTAMP():以 UNIX 时间戳的形式返回当前时间UNIX_TIMESTAMP(date):将时间 date 以 UNIX 时间戳的形式返回FROM_UNIXTIME(timestamp):将 UNIX 时间戳的时间转换为普通格式的时间
UNIX 时间戳(UNIX Timestamp)是指从 1970 年 1 月 1 日 00:00:00 UTC(协调世界时)开始所经过的秒数
1 | SELECT UNIX_TIMESTAMP(now()), -- 1739182869 精确到时分秒 |
3.3 获取月份、星期、星期数、天数等

3.4 日期的操作函数
EXTRACT(type FROM date):返回指定日期中特定的部分,type 指定返回的值
具体的 type 类型可以自行查询
3.5 日期的格式化与解析
1 | # 格式化输出 |
1 | # 解析为标准日期形式 |
4 流程控制函数【重要】
根据不同的条件,执行不同的处理流程,类似于其他语言中的 if for while
4.1 IF() 函数
IF(value, value1, value2):如果value的值为TRUE,返回value1,否则返回value2
1 | SELECT IF(TRUE, 'value1', 'value2'); -- 'value1' |
4.2 IFNULL(value1, value2) 函数
IFNULL(value1, value2):如果value1不为NULL,返回value1,否则返回value2
1 | SELECT IFNULL(NULL, 'value2'); -- NULL |
4.3 按条件返回结果
CASE WHEN 条件1 THEN 结果1 WHEN 条件2 THEN 结果2 [ELSE 结果3] END 列名:如果条件1成立,则返回结果1;如果条件2成立,则返回结果2;如果条件3成立,则返回结果3
格式:
1 | SELECT 列名1, |
例如:按照 salary 给员工增加一个字段 "level of salary"
1 | SELECT employee_id, |

4.4 按数值返回结果
CASE 列名1 WHEN num1 THEN 结果1 WHEN num2 THEN 结果2 ELSE 结果3 END 列名2:如果列名1这行的值等于num1则返回结果1;若这行的值等于num2则返回结果2;否则返回结果3,最终存入列名2
格式
1 | SELECT 列名1, |
例如:按照 region_id 填充 region_name
1 | -- 法一:多表连接 |

4.5 一些练习
- 计算年工资,考虑到奖金
1 | SELECT employee_id, |
- 按照职位调整薪水,同时补充职位全程
1 | SELECT e.last_name, |

5 加密与解密函数【数据库安全】

因为安全性问题,在
MySQL 8.0版本后PASSWORD(str)ENCODE()DECODE()函数均被移除
5.1 MD5 和 SHA 加密
1 | SELECT MD5('mysql') AS "md5 key"; -- 81c3b080dad537de7e10e0987a4bf52e |
5.2 加密和解密
使用 AES_ENCRYPT() 和 AES_DECRYPT() 函数实现 ENCODE 和 DECODE 功能
1 | mysql> SELECT AES_ENCRYPT('mysql', 'seed') AS encrypted_data; |
1 | mysql> SELECT AES_DECRYPT(AES_ENCRYPT('mysql', 'seed'), 'seed') AS decrypted_data; |
1 | mysql> SELECT CAST(AES_DECRYPT(AES_ENCRYPT('mysql', 'seed'), 'seed') AS CHAR) AS decrypted_data; |
容易得知,
AES_ENCRYPTAES_DECRYPT互为反函数
6 获取 MySQL 相关信息

- MySQL 版本号
1 | mysql> SELECT VERSION(); |
- 当前数据库
1 | mysql> SELECT DATABASE(); |
- 当前连接 MySQL 的用户名,返回结果格式为
"主机名@用户名"
1 | mysql> SELECT USER(), CURRENT_USER(), SYSTEM_USER(), SESSION_USER(); |
- 字符集和比较规则
1 | mysql> SELECT CHARSET('ABC'), COLLATION('ABC'); |
7 其他函数
- 格式化输出
FORMAT(value, n) :返回对数字 value 进行格式化后的结果数据,n表示四舍五入保留到小数点后 n 位
1 | -- n <= 0 均表示保留整数 |
- IP 转换
INET_ATON(ipvalue) :将以点分隔的IP地址转化为一个数字
INET_NTOA(value) :将数字形式的IP地址转化为以点分隔的IP地址
1 | mysql> SELECT INET_ATON('192.168.1.100') "IP - Num", INET_NTOA(3232235876) "Num - IP"; |
- 重复执行
BENCHMARK(n,expr) :将表达式 expr 重复执行n次。用于测试 MySQL 处理 expr 表达式所耗费的时间
1 | mysql> SELECT BENCHMARK(1000000, MD5('mysql')) "Once"; |
- 修改编码方式
CONVERT(value USING char_code) :将 value 所使用的字符编码修改为 char_code
1 | mysql> SELECT CHARSET('mysql') "Origin", CHARSET(CONVERT('mysql' USING 'utf8')) "Convert to utf8"; |



