【收藏夹吃灰系列】MySQL 常用函数细致总结

前言

这是我参与11月更文挑战的第1天,活动详情查看:2021最后一次更文挑战MySQL 常用函数不熟练?看我这篇就够了!!

▶ MySQL 常用函数总览

MySQL 常用函数.png

★ 字符串函数

LENGTH(str)

掌握指数:★★★★

函数说明:

返回 str 字符串字节长度

注意:

  • 英文的一个字符为 1 个字节
  • GBK 编码的为 2 个字节
  • UTF-8 编码的汉字为 3 个字节

SQL 语句示例:

1
2
3
4
5
sql复制代码
# 英文字符串字节长度
select length('HUALEI'); # 6

select length('大家好'); # 9

INSERT(str,pos,len,newstr)

掌握指数:★★★

函数说明:

str 中第 pos 位置开始插入长度为 lennewStr 字符串

SQL 语句示例:

如果我想给 str = 'HUALEI' ,想用 insert() 函数将其拼接成 “HUALEI is a hansome boy.”,那我该怎么做呢?

1
2
3
4
5
6
7
8
9
10
sql复制代码
select insert('HUALEI', length('HUALEI')+1, length('is a hansome boy.'), 'is a hansome boy.'); # HUALEI

or

select insert('HUALEI', length('HUALEI')+2, length('is a hansome boy.'), 'is a hansome boy.'); # HUALEI

but answer:

select insert('HUALEI ', length('HUALEI')+2, length('is a hansome boy.'), 'is a hansome boy.'); # HUALEI is a hansome boy.

注意: MySQL 中从 1 开始算下标,插入要满足 pos <= length(str)

那如果是中文汉字字符串呢,如何让 “青花瓷” 变成 “青花烤瓷”,“苏格拉底广场” 变成 “苏格拉底广场舞” ?

1
2
3
4
sql复制代码    
select insert('青花瓷', 3, length('烤瓷'), '烤瓷'); # 青花烤瓷

select insert('苏格拉底广场', 7, length('舞'), '舞'); # 苏格拉底广场舞

第一个 SQLpos => 3 为汉字字符串的下标索引,从第三个汉字字符开始插入长度为 length('烤瓷')'烤瓷' ;再看第二个 SQL7 大于字符个数,但是并不大于 length('苏格拉底广场') => 18 ,所以新字符串在最后一个位置上插入成功。

LEFT(str,len)

掌握指数:★★★

函数说明:

从字符串 str 左边开始截取长度为 len 的字符串

SQL 语句示例:

1
2
sql复制代码
select left('HUALEI', 3); # HUA

那 “大家好” 这个汉字字符串我想左截取出 “大家”,该如何做呢?

1
2
sql复制代码
select left('大家好', length('大家')); # 大家好

奇怪,截取的结果和预期不一样,为什么呢?

注意: 这里的 len 还是并不是通过 length() 而是通过 char_length() 得到的,从 1 开始到 len 即为截取的目标字符串。

所以,对于中文字符串来说,正确的写法应该是:

select left('大家好', 2); # 大家

RIGHT(str,len)

掌握指数:★★★

函数说明:

从字符串 str 右边开始截取长度为 len 的字符串

SQL 语句示例:

1
2
3
4
sql复制代码
select right('HUALEI', 3); # LEI

select right('大家好', 1); # 好

不赘述,和 LEFT() 一个道理。

SUBSTR(str FROM pos) <=> SUBSTR(str,pos) SUBSTR(str FROM pos FOR len) <=> SUBSTR(str,pos,len)

掌握指数:★★★★

函数说明:

str 的第 pos 个位置开始截取长度为 len 的子串,如果没有 len 参数则截取到末尾

SQL 语句示例:

1
2
3
4
5
6
7
8
9
10
11
sql复制代码
select substr('abcdefg' from 2); # bcdefg
# 等价于
select substr('abcdefg', 2); # bcdefg

select substr('abcd' from 1 for 3); # abc
# 等价于
select substr('abcd', 1, 3); # abc

# 这里的 len 理解为从 pos 开始截取几个汉字
select substr('大家好', 2, 1); # 家

STRCMP(expr1,expr2)

掌握指数:★★★

函数说明:

expr1 > expr2 => 返回 1expr1 = expr2 => 返回 0expr1 < expr2 => 返回 -1

SQL 语句示例:

1
2
3
4
5
6
7
8
sql复制代码
select strcmp('bbcd','bacd'); # 对应位置上的字符对应相比,返回 1

select strcmp('你好', '你好'); # 两个字符串一模一样,返回 0

select strcmp('ABC','abc'); # 不区分大小写,返回 0

select strcmp('abadf','abadfe'); # 后面大,返回-1

CONCAT(str1,str2,…)

掌握指数:★★★★

函数说明:

str1str2 … 等字符串连接成一个新的字符串

SQL 语句示例:

1
2
3
4
sql复制代码
select concat('hel','llo'); # hello

select concat('大家','好'); # 大家好

注意: 只要连接的字符串中存在一个 null 值,最终结果也将是 null

1
2
3
4
sql复制代码
select concat(null, 'abc'); # null

select concat('abc',null); # null

LOCATE(substr,str) | POSITION(substr IN str) | INSTR(str,substr)

掌握指数:★★★★

函数说明:

返回子串 substr 在父串 str 中的开始位置,如果父串中压根就不包含子串那么返回 0

SQL 语句示例:

1
2
3
4
5
6
7
8
9
10
sql复制代码
select locate('LEI', 'HUALEI'); # 子串 'LEI' 在父串 'HUALEI' 中的开始位置是 4
select locate('LEI ', 'HUALEI'); # 子串不存在,返回 0

select position('LEI' in 'HUALEI'); # 子串 'LEI' 在父串 'HUALEI' 中的开始位置是 4
select position('LEI ' in 'HUALEI'); # 子串不存在,返回 0

select instr('HUALEI', 'LEI'); # 4

select instr('HUALEI', 'LEI '); # 0

小结:

  • 三个函数都能拿到子串在父串中的开始位置
  • locate()position() 函数基本类似,就是参数列表不同,后者使用 in 表示子串在父串里面中的 position 位置,写起来比较好理解,更推荐使用
  • instr()locate() 唯一不同的就是参数位置交换了,注意别搞混淆写反了

LOWER(str) | UPPER(str)

掌握指数:★★★

函数说明:

str 字符串全部小写(LOWER)/大写(UPPER

SQL 语句示例:

1
2
3
4
5
6
sql复制代码
# 小写化
select lower('HUALEI'); # hualei

# 大写话
select upper('hualei'); # HUALEI

注意: 仅对英文字符串有效,中文字符串无效。

1
2
sql复制代码
select lower('大家好,我是 HUALEI'); # 大家好,我是 hualei

LTRIM(str) | RTRIM(str) | TRIM([remstr FROM] str)

掌握指数:★★★★

函数说明:

去除 str 字符串中的空格

SQL 语句示例:

1
2
3
4
5
6
sql复制代码
select ltrim(' HUALEI'); # HUALEI

select rtim('大家好! '); # 大家好!

select trim(' HUALEI '); # HUALEI

注意: trim() 函数只会去除 str 字符串前后的空格并不会去除所有空格!

1
2
sql复制代码
select trim(' HUA LEI '); # HUA LEI

REPEAT(str,count)

掌握指数:★★

函数说明:

返回 str 重复 count 遍后的结果

SQL 语句示例:

1
2
3
4
sql复制代码
select repeat('HUALEI ', 5); # HUALEI HUALEI HUALEI HUALEI HUALEI

select repeat('雷猴啊', 2); # 雷猴啊雷猴啊

REVERSE(str)

掌握指数:★★

函数说明:

将字符串 str 按倒序反过来

SQL 语句示例:

1
2
3
4
sql复制代码
select reverse('我被反过来了'); # 了来过反被我

select reverse('HUALEI'); # IELAUH

RPAD(str,len,padstr) | LPAD(str,len,padstr)

掌握指数:★★★

函数说明:

指定 str 字符串长度 lenlen > length(str) 不足用 padstr 向右/左填充;len < length(str) 充足则根据指定长度进行截取。

SQL 语句示例:

1
2
3
4
5
6
7
8
9
10
sql复制代码
select rpad('大家', 3, '好'); # 大家好

select rpad('HUALEI', length('HUALEI')+length(' NB'), ' NB'); # HUALEI NB

select length('大家好'); # 9

select lpad('SQL', 3, 'My'); # SQL

select lpad('SQL', length('MySQL'), 'My'); # MySQL

★ 数学函数

FORMAT(X,D) | ROUND(X) | ROUND(X,D)

掌握指数:★★★★

函数说明:

对 X 四舍五入保留小数点后 D 位

SQL 语句示例:

1
2
3
4
5
6
7
sql复制代码
select format(3.1415926,3); # 3.142
# 等价于
select ROUND(3.1415926, 3); # 3.142

# 无保留位数时,取整
select round(3.1415926); # 3

CEIL(X) | FLOOR(X)

掌握指数:★★★★

函数说明:

ceil 天花板(向更大值方向)取整floor 地板(向更小值方向)取整

SQL 语句示例:

1
2
3
4
5
6
7
8
sql复制代码
# 向上取整
select ceil(3.5); # 4
select ceil(-3.5); # -3

# 向下取整
select floor(3.5); # 3
select floor(-3.5); # -4

MOD(N,M)

掌握指数:★★★

函数说明:

N / M 的余数,等价于 N % M

SQL 语句示例:

1
2
3
4
sql复制代码
select mod(10, 3); # 1
# 等价于
select 10 % 3; # 1

POW(X,Y) | POWER(X,Y)

掌握指数:★★★

函数说明:

返回 X 的 Y 次方

SQL 语句示例:

1
2
3
4
sql复制代码
select pow(2, 10); # 2^10 = 1024
# 也可以写作
select power(2, 10); # 2^10 = 1024

SQRT(X)

掌握指数:★★★

函数说明:

返回 X 的平方根,也就是对 X 开平方

SQL 语句示例:

1
2
3
4
sql复制代码
select sqrt(100); # 10

select sqrt(2); # 根号 2 => 1.4142135623730951

GREATEST(expr1, expr2, expr3, …) | LEAST(expr1, expr2, expr3, …)

掌握指数:★★★

函数说明:

返回参数列表中最大/最小值

注意: 参数列表可以是字符序列。

SQL 语句示例:

1
2
3
4
5
6
7
8
sql复制代码
select greatest(1,2,3,4,51,6,7,8); # 51

select greatest('Java', 'MySQL', 'JavaScript'); # MySQL

select least(-1,2,3,4,5,6,7,8); # -1

select least('Java', 'MySQL', 'JavaScript'); # Java

RAND()

掌握指数:★★★★★

函数说明:

返回 (0, 1) 之间的随机数

SQL 语句示例:

1
2
3
4
5
6
7
sql复制代码
select rand(CURRENT_TIMESTAMP); # 给定种子值,这里给当前时间戳作为值,保证相对随机

select format(rand()*100, 0); # 产生 (0, 100) 之间的随机整数
select round(rand()*100); # 产生 (0, 100) 之间的随机整数

select ... order by rand() limit N; # 随机查询取 N 条记录

聚合函数 MAX(expr) | MIN(expr) | SUM(expr) | COUNT(expr) | AVG([DISTINCT] expr)

掌握指数:★★★★★

函数说明:

聚合函数,配合 group by 使用,用来求最大、小值/求和/计数/求平均值

SQL 语句示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
sql复制代码
# 查询男同事里薪水最高的人
select max(salary) from emp where sex = '男';

# 查询女同事里薪水最少的人
select min(salary) from emp where sex = '女';

# 查询所有姓王的学生的个人总成绩
select sum(sscore) 姓王的学生的个人总成绩 from score where sid in (select sid from student stu where stu.sname like '王%') group by sid;

# 查询女同事的人数
select count(id) 女同事的人数 from emp group by sex having sex = '女';

# 查询平均薪水
select avg(salary) 平均薪水 from emp;

注意:

  • 除非另有说明,否则聚合函数会忽略 null
  • 如果在不包含 group by 子句的语句中使用聚合函数,就等效于对所有行进行分组,结果总是有一行
  • 时间类型的值对 sum()avg() 无效!它们会将其换成数字,丢弃第一个非数字字符后的所有信息

另外,聚合函数可以传入独立的表达式作为参数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
sql复制代码
# 查询分数在 80 分及以上人数
select count(1) from score where sscore >= 80;
# 等价于
select count(if(sscore >= 80, 1, null)) from score;

# 查询分数在 80 分及以上总分
select sum(sscore) from score where sscore >= 80;
# 等价于
select sum(if(sscore>=80, sscore, null)) from score;

# 查询分数在 80 分及以上平均分
select avg(sscore) from score where sscore >= 80;
# 等价于
select avg(if(sscore>=80, sscore, null)) from score;

★ 日期函数

CURDATE() <=> CURRENT_DATE

掌握指数:★★★★

函数说明:

返回当前日期,格式为 YYYY-MM-dd

SQL 语句示例:

1
2
3
4
sql复制代码
select curdate(); # 2021-11-07

select current_date; # 2021-11-07

CURTIME() <=> CURRENT_TIME

掌握指数:★★★★

函数说明:

返回当前时间,格式为 HH:mm:ss

SQL 语句示例:

1
2
3
4
sql复制代码
select curtime(); # 10:31:23

select current_time; # 10:31:23

NOW() <=> CURRENT_TIMESTAMP

掌握指数:★★★★

函数说明:

返回当前日期时间,格式为 YYYY-MM-dd HH:mm:ss

SQL 语句示例:

1
2
3
4
sql复制代码
select now(); # 2021-11-07 10:31:46

select current_timestamp; # 2021-11-07 10:31:46

DAY(date) | DAYOFWEEK(date) | DAYOFMONTH(date) | DAYOFYEAR(date)

掌握指数:★★★★

函数说明:

返回 datedd / 这一天是这一周/月/年中的第几天

SQL 语句示例:

1
2
3
4
5
6
7
8
9
10
11
12
sql复制代码
# 取出 date 中的天
select day('2021-11-07'); # 7

# 一周中的第几天
select dayofweek(now()); # 星期天(Sunday) -> 返回 1

# 一个月中的第几天
select dayofmonth(now()); # 7

# 一年中的第几天
select dayofyear(now()); # 311

WEEK(date[,mode]) | WEEKOFYEAR(date)

掌握指数:★★★

函数说明:

Mode First day of week
0 Sunday => 1
1 Monday => 1

使用 mode 指定星期天是一周中的第一天还是星期一,然后根据这个标准判断 date 是一年的第几周,返回结果 (0, 52)WEEKOFYEAR() 总是以星期一作为一周的开始,即 mode 固定就是 1

SQL 语句示例:

1
2
3
4
5
6
7
8
9
sql复制代码
# 默认,mode => 0,星期天(Sunday)=> 1
select week('2021-11-07'); # 45
select week('2021-11-07', 0); # 45

# 星期一(Monday)=> 1
select week('2021-11-07', 1); # 44
# 等价于
select weekofyear('2021-11-07'); # 44

MONTH(date) | QUARTER(date)

掌握指数:★★★

函数说明:

返回 date 中的月份/所属季度

SQL 语句示例:

1
2
3
4
5
sql复制代码
select month(now()); # 11

# 第一季度(1, 2, 3)第二季度(4, 5, 6)第三季度(7, 8, 9)第四季度(10, 11, 12)
select quarter(curdate()); # 4

YEAR(date) | YEARWEEK(date,mode)

掌握指数:★★★★

函数说明:

返回 date 中的年份/年份+第几周

SQL 语句示例:

1
2
3
4
5
6
7
8
9
10
sql复制代码
select year(curdate()); # 2021

# 默认 mode = 0,星期天(Sunday)=> 1
select yearweek('2021-11-07'); # 202145
# 等价于
select YEARWEEK('2021-11-07', 0); # 202145

# 星期一(Monday) => 1
select YEARWEEK('2021-11-07', 1); # 202144

DAYNAME(date) | MONTHNAME(date)

掌握指数:★★

函数说明:

返回该天/月英文名

SQL 语句示例:

1
2
3
4
sql复制代码
select dayname('2021-11-07'); # Sunday 星期天

select monthname('2021-11-07'); # November 11 月

STR_TO_DATE(str,format) | DATE_FORMAT(date,format)

掌握指数:★★★★★

函数说明:

根据 date 字符串的格式,转换成日期,相反地,可以将 date 转换成指定格式的字符串

SQL 语句示例:

1
2
3
4
5
6
7
sql复制代码
# 字符串转 date 类型
select str_to_date('2021年11月07日', '%Y年%m月%d日'); # 2021-11-07
select str_to_date('2021年11月07日 12点28分34秒', '%Y年%m月%d日 %H点%i分%s秒'); # 2021-11-07 12:28:34

# date 转指定格式的字符串
select date_format(now(), '%Y年%m月%d日 %H点%i分%s秒'); # 2021年11月07日 11点29分56秒

DATEDIFF(expr1,expr2)

掌握指数:★★★★★

函数说明:

返回两个 date 相隔的天数

SQL 语句示例:

1
2
3
4
sql复制代码
select concat(datediff(curdate(), '2021-01-01'), '天') as '距离开年以来已经过了'; # 312天

select concat(datediff(str_to_date(concat(year(now()), '/12/31'), '%Y/%m/%d'), now()), '天') as '距离年末仅剩'; # 52天

DATE_ADD(date,INTERVAL expr unit) | DATE_SUB(date,INTERVAL expr unit)

掌握指数:★★★★★

函数说明:

date 做加减法

SQL 语句示例:

1
2
3
4
5
6
7
8
9
10
11
sql复制代码
select ceil(rand()*31); # (0, 31]
# 将当前时间戳加上 (0, 31] 区间中的随机 DAY 天数
select date_add(CURRENT_TIMESTAMP, interval ( ceil(rand()*31) ) DAY );

select ceil(rand()*4); # [1, 4]
# 将当前时间戳加上 [1, 4] 区间中的随机 WEEK 周数
select date_add(now(), interval ( ceil(rand()*4) ) WEEK );

# 相反地,对指定 date 做减法,将当前时间戳减去 [0, 10] 区间中的随机 YEAR 年数
select date_sub(CURRENT_TIMESTAMP, interval ( round(rand(CURRENT_TIME)*11) ) YEAR );

TO_DAYS(date) | FROM_DAYS(N)

掌握指数:★★

函数说明:

给定一个 date ,返回从公元 0 年到 date 的天数

小知识:历史并不存在公元 0 年,但 0 年是公元位数对齐的基础

SQL 语句示例:

1
2
3
4
5
6
7
8
sql复制代码
select to_days('2021-11-07'); # 738466
# 并不完全等价,to_days() 包含当天,而 datediff() 不然
select datediff('2021-11-07','0-01-01'); # 738465

# to_days() 的逆运用,给定一个从公元 0 年开始的天数,返回一个 date
select from_days(737515); # 2019-4-1
select from_days(to_days('2021-11-07')); # 2021-11-07

☛ 流程控制函数

IF(expr1,expr2,expr3)

掌握指数:★★★★

函数说明:

判断 expr1 表达式真假,真返回 expr2,否则返回 expr3

SQL 语句示例:

1
2
sql复制代码
select if(10 > 5, '10 更大', '5 更大'); # 10 更大

IFNULL(expr1,expr2) | NULLIF(expr1,expr2)

掌握指数:★★★

函数说明:

IFNULL 用来判断 expr1 是否为 null,如果不是则返回 expr2 ,否则返回 expr1NULLIF 则是用来判断 expr1、2 是否相等,相等则返回 null,否则返回 expr1

SQL 语句示例:

1
2
3
4
5
6
7
8
9
10
11
12
sql复制代码
# expr1 is not null.return expr1
select ifnull('exp1 is not null', null); # exp1 is not null
# expr1 is null.return expr2
select ifnull(null, 'exp1 is null'); # exp1 is null

select nullif('HUALEI', 'hualei'); # 相等返回 null
# 等价于(不区分大小写)
select nullif('HUALEI', 'HUALEI'); # 相等返回 null

# expr1 != expr2
select nullif('HUALEI', null); # HUALEI

注意: expr1 != null ,否则返回 null

1
sql复制代码select nullif(null, 'HUALEI'); # null

IF … ELSE 语句

掌握指数:★★★★

函数说明:

写法不同于 IF() 函数

语法:

1
2
3
4
5
6
sql复制代码
IF search_condition THEN
statement_list
ELSE
statement_list
END IF;

SWITCH … CASE 语句

掌握指数:★★★★

函数说明:

开关语句

语法:

1
2
3
4
5
6
7
sql复制代码
CASE case_value
WHEN when_value THEN
  statement_list
ELSE
  statement_list
END;

☛ 消息摘要函数

PASSWORD(str)

掌握指数:★★★

函数说明:

计算并返回密码字符串

SQL 语句示例:

1
2
3
4
sql复制代码
select PASSWORD('abc') # *0D3CED9BEC10A777AEC23CCC353A8C08A633045E

select PASSWORD('ABC') # *71B101096C51D03995285042443F5C44D59C8A31

注意: 该函数在 MySQL8.0.11 版本中被移除了。

MD5(str)

掌握指数:★★★★

函数说明:

计算 MD5 总和校验码

SQL 语句示例:

1
2
sql复制代码
select MD5("abc"); # 900150983cd24fb0d6963f7d28e17f72

SHA(str) | SHA1(str)

掌握指数:★★★★

函数说明:

计算 SHA/SHA1 总和校验码

SQL 语句示例:

1
2
3
4
sql复制代码
select SHA('abc') # a9993e364706816aba3e25717850c26c9cd0d89d
# 等价于
select SHA1('abc') # a9993e364706816aba3e25717850c26c9cd0d89d

☛ 对称加密函数

ENCODE(str,pass_str) | DECODE(crypt_str,pass_str)

掌握指数:★★★★

函数说明:

通过公共密钥加密(Encode 编码)/解密(Decode 解码)

SQL 语句示例:

1
2
3
4
5
6
sql复制代码
# 'password' 作为公钥加密字符串信息 'HUALEI'
select encode('HUALEI', 'password'); # ���e

# 将加密后的密文通过公钥 'password' 进行解密,从而得到加密前的明文
select decode(encode('HUALEI', 'password'), 'password'); # HUALEI

AES_ENCRYPT(str,key_str) | AES_DECRYPT(crypt_str,key_str) | DES_ENCRYPT(str[,{key_num|key_str}]) | DES_DECRYPT(crypt_str[,key_str])

掌握指数:★★★★

函数说明:

通过额 AES(Advanced Encryption Standard 高级加密标准,作为 DES 算法的替代品) / DES(Data Encryption Standard 数据加密标准) 算法对称加密信息

SQL 语句示例:

1
2
3
4
5
6
7
8
9
10
sql复制代码
# AES 算法加密,公钥为 'salt'
select aes_encrypt('HUALEI', 'salt'); # �ɫD�b*�ճ�ϐe�
# AES 算法解密
select aes_decrypt(aes_encrypt('HUALEI', 'salt'), 'salt'); # abc

# DES 算法加密,公钥为 'password'
select des_encrypt('HUALEI', 'password'); # ��o�#�
# DES 算法解密
select des_decrypt(des_encrypt('HUALEI', 'password'), 'password'); # HUALEI

☛ 系统信息函数

VERSION()

掌握指数:★★★★

函数说明:

返回当前 MySQL 版本号

SQL 语句示例:

1
2
sql复制代码
select version(); # 5.7.31-log

USER() | CURRENT_USER

掌握指数:★★★★

函数说明:

返回当前用户角色

SQL 语句示例:

1
2
3
4
sql复制代码
select user(); # root@localhost
# 等价于
select current_user; # root@localhost

DATABASE()

掌握指数:★★★★

函数说明:

返回当前所在数据库名

SQL 语句示例:

1
2
sql复制代码
select database(); # mysql

CONNECTION_ID()

掌握指数:★★★

函数说明:

返回当前用户连接数

SQL 语句示例:

1
2
sql复制代码
select connect_id(); # 38

函数全概述

以上全部函数,我将它们归纳成一张思维导图,非常直观,供大家学习参考:

MySQL 常用函数.jpg

结尾

撰文不易,欢迎大家点赞、评论,你的关注、点赞是我坚持的不懈动力,感谢大家能够看到这里!Peace & Love。

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%