前言
为了简化操作,MySQL 提供了大量的函数,会对传递进来的参数进行处理,并返回一个处理结果,也就是返回一个值。MySQL 包含了大量并且丰富的函数,这里只是对 MySQL 常用函数进行简单的分类,大概包括数值型函数、字符串型函数、日期时间函数、聚合函数等。剩下的比较罕见的函数就不再整理了,小伙伴们可以到「MySQL 官网」查询。
MySQL函数是MySQL数据库提供的内部函数,这些内部函数可以帮助用户更加方便的处理表中的数据,可以使MySQL数据库的功能更加强大。SELECT语句及其条件表达式都可以使用这些函数。同时,INSERT、UPDATE、DELECT语句及其条件表达式也可以使用这些函数。例如,表中的某个数据是负数,现在需要将这个数据显示为正数。这就可以使用绝对值函数。
一、字符串函数
字符串函数是最常用的函数,可以对字符串类型数据进行处理,MySQL也支持许多字符串函数,以下是MySQL支持的字符串函数的表。
函数名称 | 作 用 |
---|---|
ASCII(s) | 获取字符串的 ASCII 码 |
CHAR_LENGTH(s) | 返回字符串的长度(以字符为单位) |
CHARACTER_LENGTH(s) | 返回字符串的长度(以字符为单位) |
CONCAT(s1,s2…,sn) | 合并字符串函数,将两个或多个表达式相加。 如果该函数中的任何参数为 null,返回结果为 null |
CONCAT_WS(x, s1,s2…sn) | 同 CONCAT 函数,但是每个字符串之间要加上 x,x 可以是分隔符 |
FIELD(s,s1,s2…) | 返回第一个字符串 s 在字符串列表(s1,s2…)中的位置 |
FIND_IN_SET(s1,s2) | 返回在字符串s2中与s1匹配的字符串的位置 |
FORMAT(x,n) | 将数字 x 进行格式化 “#,###.##”,保留到小数点后 n 位,最后一位四舍五入 |
INSERT | 替换字符串函数 |
INSTR(s1,x,len,s2) | 字符串 s2 替换 s1 的 x 位置开始长度为 len 的字符串 |
LCASE | 将字符串转换为小写 |
LEFT(s,n) | 从左侧字截取符串,返回字符串 s 的前 n 个字符 |
LENGTH | 返回字符串的长度(以字节为单位) |
LOCATE(s1,s) | 从字符串 s 中获取 s1 的开始位置 |
LOWER | 将字符串转换为小写 |
LPAD(s1,len,s2) | 在字符串 s1 的开始处填充字符串 s2,使字符串长度达到 len |
LTRIM(s) | 去掉字符串 s 开始处的空格 |
MID(s,n,len) | 从字符串 s 的 n 位置截取长度为 len 的子字符串 |
POSITION(s1 IN s) | 从字符串 s 中获取 s1 的开始位置 |
REPEAT(s,n) | 将字符串 s 重复 n 次 |
REPLACE(s,s1,s2) | 字符串替换函数,将字符串 s2 替代字符串 s 中的字符串 s1 |
REVERSE | 字符串反转(逆序)函数,返回与原始字符串顺序相反的字符串 |
RIGHT(s,n) | 从右侧字截取符串,返回字符串 s 的后 n 个字符 |
RPAD(s1,len,s2) | 在字符串 s1 的结尾处添加字符串 s2,使字符串的长度达到 len |
RTRIM(s) | 去掉字符串 s 结尾处的空格 |
SPACE(n) | 返回 n 个空格 |
STRCMP(s1,s2) | 比较字符串 s1 和 s2,如果相等返回 0 ,如果 s1>s2 返回 1,如果 s1<s2 返回 -1 |
SUBSTR(s, start, length) | 从字符串 s 的 start 位置截取长度为 length 的子字符串 |
SUBSTRING(s, start, length) | 截取字符串,从字符串 s 的 start 位置截取长度为 length 的子字符串 |
TRIM(s) | 删除字符串 s 开始和结尾处的空格 |
UCASE(s) | 将字符串转换为大写 |
UPPER | 将字符串中的字母转换为大写 |
二、数学函数
除去加减乘除的符号外,数字计算上,MySQL
也提供了一些常用的数学计算函数,主要用于处理数字,包括整型、浮点数等。数学函数包括绝对值函数、正弦函数、余弦函数、获取随机数的函数等。
函数名称 | 作 用 |
---|---|
ABS(x) | 返回数字的绝对值 |
ACOS | 求反余弦值,与函数 COS 互为反函数 |
ASIN | 求反正弦值,与函数 SIN 互为反函数 |
ATAN(x) | 求反正切值,与函数 TAN 互为反函数 |
CEIL(x) | 返回不小于参数的最小整数,即向上取整 |
CEILING) | 返回不小于参数的最小整数,即向上取整 |
COS(x) | 求余弦值 |
COT(x) | 求余切值 |
DEGREES(x) | 将弧度转换为角度 |
DIV | 用于整数除法 |
EXP(x) | 返回 e 的 x 次方 |
FLOOR(x) | 向下取整,返回小于或等于 x 的最大整数 |
GREATEST(expr1, expr2, …) | 返回列表中的最大值 |
LEAST(expr1, expr2, …) | 返回列表中的最小值 |
LOG2(x) | 返回以 2 为底的对数 |
LOG10 | 返回以10为底的数字的自然对数 |
LOG | 返回一个数字的自然对数 |
MOD(x,y) | 返回 x 除以 y 以后的余数 |
PI() | 返回圆周率(3.141593) |
POW(x,y) | 返回 x 的 y 次方 |
POWER(x,y) | 返回 x 的 y 次方 |
RADIANS(x) | 将角度转换为弧度 |
RAND | 生成一个0~1之间的随机数,传入整数参数是,用来产生重复序列 |
ROUND | 对所传参数进行四舍五入 |
SIGN | 返回参数的符号 |
SIN | 求正弦值 |
SQRT | 求二次方根 |
TAN(x) | 求正切值 |
TRUNCATE(x,y) | 返回数值 x 保留到小数点后 y 位的值 |
三、日期时间函数
3.1 日期时间格式化
DATE_FORMAT(date,format)
根据format字符串格式化date值,在format字符串中可用标志符。具体的参数如下:
format | 含义 |
---|---|
%a | 工作日的缩写名称(Sun~Sat) |
%b | 月份的缩写名称(Jan…Dec) |
%c | 月份,数字形式(0~12) |
%D | 带有英语后缀的该月日期(0th, 2st, 3nd,…) |
%d | 该月日期,数字形式(00~31) |
%e | 该月日期,数字形式((0~31) |
%f | 微秒(000000 …999999) |
%H | 以 2 位数表示 24 小时(00~23) |
%h, %I | 以 2 位数表示 12 小时(01~12) |
%i | 分钟,数值(00-59) |
%j | —年中的天数(001~366) |
%k | 以 24 小时(0~23)表示 |
%l | 以12小时(1~12)表示 |
%M | 月份名称(January~December) |
%m | 月份,数字形式(00~12) |
%p | 上午(AM) 或下午(PM) |
%r | 时间,12小时制(小时 (hh): 分钟 (mm) : 秒数 (ss) 后加 AM 或 PM) |
%S, %s | 以 2 位数形式表示秒(00~59) |
%T | 时间,24 小时制(小时 (hh): 分钟 (mm): 秒数 (ss)) |
%U | 周(00~53),其中周日为每周的第一天 |
%u | 周(00~53),其中周一为每周的第一天 |
%V | 周(01~53),其中周日为每周的第一天,和%X同时使用 |
%v | 周(01~53),其中周一为每周的第一天,和%x同时使用 |
%W | 星期标识(周日、周一、周二…周六) |
%w | —周中的每日(0= 周日…6= 周六) |
%X | 该周的年份,其中周日为每周的第一天,数字形式,4 位数,和%V同时使用 |
%x | 该周的年份,其中周一为每周的第一天,数字形式,4位数,和%v同时使用 |
%Y | 4 位数形式表示年份 |
%y | 2 位数形式表示年份 |
具体执行结果如下:
select DATE_FORMAT('2022-12-11 00:22:30','%Y/%m/%d');
select DATE_FORMAT('2022-12-11 00:22:30','%Y%m%d');
select DATE_FORMAT('2022-12-11 00:22:30','%m');
select DATE_FORMAT('2022-12-11 00:22:30','%H');
3.2 日期函数
函数名称 | 作 用 |
---|---|
CURDATE() | 当前系统的日期 |
CURRENT_DATE() | 返回当前日期 |
CURRENT_TIME | 返回当前系统的时间 |
CURRENT_TIMESTAMP() | 返回当前日期和时间 |
CURTIME() | 返回当前时间 |
DATE_FORMAT | 格式化指定的日期,根据参数返回指定格式的值 |
DATE() | 从日期或日期时间表达式中提取日期值 |
DATEDIFF(d1,d2) | 获取两个日期之间间隔,返回参数 1 减去参数 2 的值 |
DAY(date) | 返回日期值 d 的日期部分 |
DAYNAME(d) | 获取指定曰期对应的星期几的英文名称 |
DAYOFMONTH(d) | 获取指定日期是一个月中是第几天,返回值范围是1~31 |
DAYOFWEEK(d) | 获取指定日期对应的一周的索引值,1 星期日,2 星期一,以此类推 |
DAYOFYEAR(d) | 获取指定曰期是一年中的第几天,返回值范围是1~366 |
FROM_DAYS(n) | 计算从 0000 年 1 月 1 日开始 n 天后的日期 |
FROM_UNIXTIME | 将 UNIX 时间戳转换为时间格式,与UNIX_TIMESTAMP互为反函数 |
HOUR(time) | 返回 t 中的小时值,返回值的范围是 0 到 23 |
LAST_DAY(d) | 返回给给定日期的那一月份的最后一天 |
LOCALTIME() | 返回当前日期和时间 |
LOCALTIMESTAMP() | 返回当前日期和时间 |
MAKETIME(hour, minute, second) | 组合时间,参数分别为小时、分钟、秒 |
MINUTE(time) | 返回 t 中的分钟值,范围是 0 到 59 |
MONTH(date) | 获取指定日期中的月份,范围为 1 到 12 |
MONTHNAME | 获取指定日期中的月份英文名称 |
NOW() | 返回当前系统的日期和时间值 |
PERIOD_ADD(period, number) | 为 年-月 组合日期添加一个时段 |
PERIOD_DIFF(period1, period2) | 返回两个时段之间的月份差值 |
QUARTER(d) | 返回日期的一年中的季度,范围为 1 到 4 |
SEC_TO_TIME(s) | 将以秒为单位的时间 s 转换为时分秒的格式,与TIME_TO_SEC 互为反函数 |
SECOND(time) | 返回 t 中的秒钟值,范围为 0 到 59 |
STR_TO_DATE(string, format) | 将字符串转变为日期 |
SUBDATE(d,n) | 日期 d 减去 n 天后的日期 |
SUBTIME(t,n) | 时间减法运算,时间 t 减去 n 秒的时间 |
SYSDATE() | 返回当前日期和时间 |
TIME_FORMAT(t,f) | 按表达式 f 的要求显示时间 t |
TIME_TO_SEC | 将时间参数转换为秒数 |
TIME(expression) | 提取传入表达式的时间部分 |
TIMEDIFF(time1, time2) | 计算时间差值 |
TO_DAYS(d) | 计算日期 d 距离 0000 年 1 月 1 日的天数 |
UNIX_TIMESTAMP | 获取UNIX时间戳函数 |
WEEK(d) | 获取指定日期是一年中的第几周,返回值的范围是否为 0〜52 或 1〜53 |
WEEKDAY(d) | 获取指定日期在一周内对应的工作日索引,0 表示星期一,1 表示星期二 |
WEEKOFYEAR(d) | 计算日期 d 是本年的第几个星期,范围是 0 到 53 |
YEAR(d) | 获取年份,范围为 1000 到 9999 |
YEARWEEK(date, mode) | 返回年份及第几周(0到53),mode 中 0 表示周天,1表示周一,以此类推 |
- 获取当前系统时间
SELECT FROM_UNIXTIME(UNIX_TIMESTAMP());
SELECT EXTRACT(YEAR_MONTH FROM CURRENT_DATE);
SELECT EXTRACT(DAY_SECOND FROM CURRENT_DATE);
SELECT EXTRACT(HOUR_MINUTE FROM CURRENT_DATE);
3.3 日期函数加减运算
函数名称 | 作 用 |
---|---|
ADDDATE(date,INTERVAL expr unit) | 向日期添加指定的时间间隔 |
ADDTIME(date,INTERVAL expr unit) | 时间加法运算,在原始时间上添加指定的时间 |
DATE_ADD(date,INTERVAL expr unit) | 向日期添加指定的时间间隔 |
DATE_SUB(date,INTERVAL expr unit) | 向日期减去指定的时间间隔 |
这里简单介绍其中的参数含义,date 参数指定开始日期或日期时间值。 expr 是一个表达式,指定要从开始日期添加或减去的间隔值,而unit则指明表达式expr应该如何被解释,其值为
unit值 | 说明 | expr 格式 |
---|---|---|
second | 秒 | seconds |
minute | 分钟 | minutes |
hour | 小时 | hours |
day | 天 | day |
month | 月 | month |
year | 年 | year |
minute_second | 分钟和秒 | minutes:seconds |
hour_minute | 小时和分钟 | hours:minutes |
day_hour | 天和小时 | hours hours |
day_minute | 天、小时、分钟 | hours hours:minutes |
day_second | 天、小时、分钟、秒 | hours hours:minutes:seconds |
year_month | 年和月 | year-month |
具体用法如下:
select DATE_ADD('2022-12-11' ,INTERVAL 1 DAY);
select DATE_ADD('2022-12-11' ,INTERVAL 1 MONTH);
select DATE_ADD('2022-12-11' ,INTERVAL -1 DAY);
3.4 关于时间的查询
- 获取年月日时分秒周
SELECT now(),dayofweek(now()),YEAR(now()),MONTH(now()),DAY(now()),HOUR(now()),MINUTE(now()),SECOND(now()),WEEK(now());
- 结合某表的常用查询
-- 今天
select * from sys_log_login where to_days(createTime) = to_days(now());
-- 查询最近一周的数据
select * from sys_log_login where DATE_SUB(CURDATE(), INTERVAL 7 DAY) <= date(createTime);
-- 查询上一周数据
SELECT * FROM sys_log_login WHERE YEARWEEK(date_format(now() ,'%Y-%m-%d'))= YEARWEEK(now()) -1
-- 近30天
SELECT *FROM sys_log_login where DATE_SUB(CURDATE(), INTERVAL 30 DAY) <= date( createTime)
-- 查询最近一月的数据
select * from sys_log_login where DATE_SUB(CURDATE(), INTERVAL 1 MONTH) <= date(createTime);
-- 查询本月数据
SELECT * FROM sys_log_login WHERE DATE_FORMAT(createTime, '%Y%m')=DATE_FORMAT(CURDATE() , '%Y%m')
-- 查询上一月数据
SELECT * FROM sys_log_login WHERE PERIOD_DIFF(date_format(now() ,'%Y%m'), date_format(createTime ,'%Y%m'))=1
-- 查询本年数据
select * from `sys_log_login` where YEAR(createTime)=YEAR(NOW());
-- 查询上一年数据
select * from `sys_log_login` where year(createTime)=year(date_sub(now(),interval 1 year));
-- 按日查询
SELECT DATE_FORMAT(createTime, '%Y-%m-%d') AS time,COUNT(*) FROM sys_log_login GROUP BY time
-- 按周查
SELECT DATE_FORMAT(createTime, '%Y-%u') AS time,COUNT(*) FROM sys_log_login GROUP BY time
-- 按月查
SELECT DATE_FORMAT(createTime,'%Y-%m') AS time,COUNT(*) FROM sys_log_login GROUP BY time
-- 按年查
SELECT DATE_FORMAT(createTime,'%Y') AS time,COUNT(*) FROM sys_log_login GROUP BY time
-- 按月分组查询
SELECT
SUM(case MONTH(createTime) WHEN 1 THEN 1 ELSE 0 END) AS 一月份,
SUM(case MONTH(createTime) WHEN 2 THEN 1 ELSE 0 END) AS 二月份,
SUM(case MONTH(createTime) WHEN 3 THEN 1 ELSE 0 END) AS 三月份,
SUM(case MONTH(createTime) WHEN 4 THEN 1 ELSE 0 END) AS 四月份,
SUM(case MONTH(createTime) WHEN 5 THEN 1 ELSE 0 END) AS 五月份,
SUM(case MONTH(createTime) WHEN 6 THEN 1 ELSE 0 END) AS 六月份,
SUM(case MONTH(createTime) WHEN 7 THEN 1 ELSE 0 END) AS 七月份,
SUM(case MONTH(createTime) WHEN 8 THEN 1 ELSE 0 END) AS 八月份,
SUM(case MONTH(createTime) WHEN 9 THEN 1 ELSE 0 END) AS 九月份,
SUM(case MONTH(createTime) WHEN 10 THEN 1 ELSE 0 END) AS 十月份,
SUM(case MONTH(createTime) WHEN 11 THEN 1 ELSE 0 END) AS 十一月份,
SUM(case MONTH(createTime) WHEN 12 THEN 1 ELSE 0 END) AS 十二月份
FROM sys_log_login
WHERE
YEAR(createTime) = YEAR(CURDATE())
四、聚合函数
聚合函数又称为组函数,一般结合分组进行使用,用来统计和计算,比如不想知道每条学生记录的确切信息,只想知道学生记录数量。聚合函数在平常的sql中十分常用,不需要查阅文档就应该保证熟练使用,这里列举如下:
函数名称 | 作 用 |
---|---|
AVG(expression) | 返回一个表达式的平均值 |
COUNT(expression) | 返回由 SELECT 语句检索的行中 expr 的非 NULL 值的计数 |
GROUP_CONCAT() | 将group by产生的同一个分组中的值连接起来,返回一个字符串结果 |
MAX(expression) | 返回字段 expression 中的最大值 |
MIN(expression) | 返回字段 expression 中的最小值 |
SUM(expression) | 返回指定字段的总和 |
需要注意的是,聚合函数不会对
null
值进行计算。由于它会略过null
值,具体业务情况需要酌情分析。
这里主要来看下 GROUP_CONCAT 函数的使用,如下所示:
select date,GROUP_CONCAT(sales) from order_details group by date order by date limit 10;
+------------+-------------------------------+
| date | GROUP_CONCAT(sales) |
+------------+-------------------------------+
| 2019-01-01 | 39,44,37,38,88,87,6,21,91,78 |
| 2019-01-02 | 70,12,63,52,80,35,14,88 |
| 2019-01-03 | 16,76,48 |
| 2019-01-04 | 42,69,99,85,49,37 |
| 2019-01-05 | 63,61,50,1,100,33,60,59,90,48 |
| 2019-01-06 | 66,66,49,14,38,94,78,16,68 |
| 2019-01-07 | 30,51,13,27,58,82,75,12 |
| 2019-01-08 | 71,50,67,46,91 |
| 2019-01-09 | 62,76,51,100,11,28,32 |
| 2019-01-10 | 13,72,38,42,67,94,76 |
五、控制流程函数
MySQL有4个函数是用来进行条件操作的,这些函数可以实现SQL的条件逻辑,允许开发者将一些应用程序业务逻辑转换到数据库后台。
函数名称 | 作 用 |
---|---|
IF(expr,v1,v2) | 如果表达式 expr 成立,返回 v1,否则返回 v2 |
IFNULL(v1,v2) | 如果 v1 的值不为 NULL,则返回 v1,否则返回 v2 |
NULLIF(arg1,arg2) | 如果arg1=arg2返回NULL;否则返回arg1 |
case when <求值表达式> then <表达式1> when <求值表达式> then <表达式2> else <表达式> end | 如果testN是真,则返回resultN,否则返回default 当一个case子句中有多个判断逻辑时、字段类型需要一致。 |
case <表达式> when <求值表达式> then <表达式1> when <求值表达式> then <表达式2> else <表达式> end | 如果test和valN相等,则返回resultN,否则返回default 当一个case子句中有多个判断逻辑时、字段类型需要一致。 |
ISNULL(expression) | 判断表达式是否为 NULL |
这里举个完整的示例,我们先看原始数据:
id | age | sex | name | score |
---|---|---|---|---|
1 | 22 | 0 | 周蓉 | 91 |
2 | 18 | 0 | 周秉昆 | 45 |
3 | 25 | 1 | 周秉义 | 92 |
4 | 22 | 1 | 蔡晓光 | 82 |
5 | 24 | 0 | 郝冬梅 | 82 |
6 | 17 | 0 | 乔春燕 | 56 |
7 | 21 | 0 | 郑娟 | 38 |
8 | 18 | 1 | 郝德宝 | 61 |
统计优秀、良好、合格、不合格人数。
select
case
when score>=90 then '优秀'
when score>=80 and score <90 then '良好'
when score>=60 and score<80 then '合格'
when score<60 then '不合格'
end as type,count(*) as '人数' from t_score group by type;
六、系统信息函数
系统信息函数用来查询MySQL数据库的系统信息。例如,查询数据库的版本,查询数据库的当前用户等。本小节将详细讲解系统信息函数的作用和使用方法。
函数名称 | 作用 |
---|---|
VERSION() | 获取MySQL版本号、连接数、数据库名 |
CONNECTION_ID() | 获取服务器的连接数,也就是到现在为止MySQL服务的连接次数 |
DATABASE() | 获取当前数据库名 |
SCHEMA() | 获取当前数据库名 |
USER() | 获取当前用户的名称 |
SYSTEM_USER() | 获取当前用户的名称 |
SESSION_USER() | 获取当前用户的名称 |
CURRENT_USER() | 获取当前用户的名称 |
CHARSET(str) | 获取字符串str的字符集,一般情况就是系统的默认字符集 |
COLLATION(str) | 获取字符串str的字符排列方式 |
LAST_INSERT_ID() | 获取最后生成的AUTO_INCREMENT值 |
七、加密函数
加密函数是MySQL中用来对数据进行加密的函数。因为数据库中有些很敏感的信息不希望被其他人看到,就应该通过加密方式来使这些数据变成看似乱码的数据。例如用户的密码,就应该经过加密。下面是各种加密函数的名称、作用和使用方法。
函数名称 | 作用 |
---|---|
PASSWORD(str) | 对字符串str进行加密。一般情况下,主要是用来给用户密码加密的 |
MD5(str) | 主要对普通的数据进行加密 |
ENCODE(str,pswd_str) | 使用字符串pswd_str来加密字符串str |
DECODE(crypt_str,pswd_str) | 使用字符串pswd_str来为crypt_str解密 |
SHA() | 计算字符串str的安全散列算法(SHA)校验和 |
SELECT ENCODE('xufeng','key');
SELECT DECODE(ENCODE('xufeng','key'),'key');#加解密放在一起
SELECT MD5('123456');
SELECT SHA('123456');
八、其它函数
函数名称 | 作 用 |
---|---|
CAST(expression AS data_type) | 用于将某种数据类型的表达式显式转换为另一种数据类型 |