mysql中的内置函数

这里主要介绍mysql丰富的内置函数。

数学函数

数学函数相对比较简单,就是涉及一些数值的计算,这里列出数学函数的功能,仅个别给出实例。

函数 作 用
ABX(x) 返回x的绝对值
CEIL(X),CEILING(x) 返回大于或等于x的最小整数
FLOOR(X) 返回小于或等于x的最大整数
RAND() 返回0~1的随机数
RAND(X) 返回0~1的随机数,x值相同时,返回的随机数相同
SIGN(x) 返回x的符号,负数,0,正数对应的符号分为-1,0,1
PI() 返回圆周率
TRUNCATE(x,y) 返回数值x保留到小数点后y位的值
ROUND(x) 返回离x最近的整数
ROUND(x,y) 保留x小数点后y位的值,但截断时要进行四舍五入
POW(x,y),POWER(x,y) 返回x的y次方
SQRT(x) 返回x的平方根
EXP(x) 返回e的x次方
MOD(x,y) 返回x除以y以后的余数
LOG(x) 返回自然对数(以e为底的对数)
LOG10(x) 返回以10为底的对数
RADLANS(x) 将角度转换为弧度
DEGREES(x) 将弧度转换为角度
SIN(x) 求正弦值
ASIN(x) 求反正弦值
COS(x) 求余弦值
aCOS(x) 求反余弦值
TAN(x) 求正切值
ATAN(x),ATAN2(x,y) 求反正切值
COT(x) 求余切值
root@testdb 09:55:30>select rand();         #返回随机值
+--------------------+
| rand() |
+--------------------+
| 0.0276665883396441 |
+--------------------+
1 row in set (0.00 sec) root@testdb 10:10:26>select rand();
+--------------------+
| rand() |
+--------------------+
| 0.9018256607482449 |
+--------------------+
1 row in set (0.00 sec) root@testdb 10:10:27>select rand(1); #x值相同,则返回相同的随机值
+---------------------+
| rand(1) |
+---------------------+
| 0.40540353712197724 |
+---------------------+
1 row in set (0.00 sec) root@testdb 10:10:29>select rand(1);
+---------------------+
| rand(1) |
+---------------------+
| 0.40540353712197724 |
+---------------------+
1 row in set (0.00 sec) root@testdb 10:10:30>

个别函数实例

ROUND(X)函数返回离x最近的整数,也就是对x进行四舍五入处理;ROUND(x,y)函数返回x保留到小数点后y位的值,截断时需要进行四舍五入处理,TRUNCATE(x,y)函数返回x保留到小数点后y位的值。

root@testdb 10:14:50>select pi(), round(pi()), round(pi(), 3), truncate(pi(),3);
+----------+-------------+----------------+------------------+
| pi() | round(pi()) | round(pi(), 3) | truncate(pi(),3) |
+----------+-------------+----------------+------------------+
| 3.141593 | 3 | 3.142 | 3.141 |
+----------+-------------+----------------+------------------+
1 row in set (0.00 sec) root@testdb 10:15:21>

mysql中内置的数学函数大致就如上面所列的,相对比较简单,在截断浮点数的时候,注意是否是采用来四舍五入的算法。

字符串函数

字符串函数是mysql中最常用的一类函数。字符串函数主要用于处理表中的字符串。字符串函数包括求字符串长度,合并字符串,在字符串中插入子串和大小写字母之间的切换等函数。主要有如下函数。

函数   作用
CHAR_LENGTH(S) 返回字符串s的字符数
LENGTH(S) 返回字符串s的长度
CONCAT(s1,s2,...) 将多个字符串合并为一个字符串
CONCAT_WS(x,S1,S2,...) 将多个字符串合并为一个字符串,但是每个字符串之间要加上x
INSERT(s1,x, len, s2) 将字符串s1中x位置开始长度为len的字符串用s2替换
UPPER(s),UCASE(s) 将字符串s的所有字母都变成大写字母
LOWER(s),LCASE(s) 将字符串s的所有字母都变为小写字母
LEFT(s,n) 返回字符串s的左边n个字符
RIGHT(s,n) 返回字符串s右边的n个字符
LPAD(s1, len, s2) 字符串s2来填充s1的开始处,使字符串长度达到len
RPAD(s1,len,s2) 字符串s2来填充s1的结尾处,使字符串长度达到len
LTRIM(s) 去掉字符串s开始处的空格
RTRIM(s) 去掉字符串s结尾处的空格
TRIM(s) 去掉字符串s开始和结尾处的空格
TRIM(s1 FROM s2) 函数去掉字符s中开始处和结尾处的字符串s1
REPEAT(s,n) 将字符串s重复n次
SPACE(n) 返回n个空格
REPLACE(s,s1,s2) 用字符串s2替换字符串s中字符串s1
STRCMP(s1,s2) 比较字符串s1和s2,这里是比较字符对应的ASCII码的大小
SUBSTRING(s,n,len) 获取字符串s中第n个位置开始长度为len的字符
MID(s,n,len) 同上
LOCATE(s1,S),POSITION(S1 IN S) 从字符串s中获取字符串s1的开始位置
INSTR(S,S1) 同上
REVERSE(S) 将字符串s的顺序反过来
ELT(N,S1,S2..) 返回第n个字符串
EXPORT_SET 看下面的说明
FIELD(s,s1,s2...) 返回第一个与字符串s匹配的字符串位置
FIND_IN_SET(S1,S2) 返回在字符串s2中与s1匹配的字符串的位置
MAKE_SET(X,S1,S2...) 按x的二进制数从s1,s2,...sn中选取字符串

比较返回的字符数与字符长度

这两个函数用英文字母不太好区别,我们使用汉语字符串如下:

root@testdb 10:15:21>select "北京", char_length("北京"),length("北京");            #在utf8编码中,每一个汉字占3个字符长度。两个字符,6个字符长度。
+--------+-----------------------+------------------+
| 北京 | char_length("北京") | length("北京") |
+--------+-----------------------+------------------+
| 北京 | 2 | 6 |
+--------+-----------------------+------------------+

合并字符串:

通过一个实例来说明两者之间的差别

root@employees 10:41:31>select concat(first_name,last_name) from employees limit 1;        #这样合成的全名中间直接连接
+------------------------------+
| concat(first_name,last_name) |
+------------------------------+
| GeorgiFacello |
+------------------------------+
1 row in set (0.01 sec)
root@employees 10:45:02>select concat_ws("-",first_name,last_name) from employees limit 1; #这样合成的全名,中间会有一个短横线连接
+-------------------------------------+
| concat_ws("-",first_name,last_name) |
+-------------------------------------+
| Georgi-Facello |
+-------------------------------------+
1 row in set (0.00 sec) root@employees 10:45:16>

替换字符串

root@employees 10:50:39>select insert("beijing",4,4,"fang");        #将“beijing”中第四个位置开始,长度为4的字符串替换为fang。
+------------------------------+
| insert("beijing",4,4,"fang") |
+------------------------------+
| beifang |
+------------------------------+
1 row in set (0.00 sec) root@employees 10:51:32>

需要说明的是,替换的字符串长度可以和原字符中要替换的长度不相等:

root@employees 10:52:53>select insert("abcdefg",2,3,"hhhhhhhh");
+----------------------------------+
| insert("abcdefg",2,3,"hhhhhhhh") |
+----------------------------------+
| ahhhhhhhhefg |
+----------------------------------+
1 row in set (0.00 sec) root@employees 10:54:25>select insert("abcdefg",2,3,"h");
+---------------------------+
| insert("abcdefg",2,3,"h") |
+---------------------------+
| ahefg |
+---------------------------+
1 row in set (0.00 sec) root@employees 10:54:31>

获取指定长度的字符串函数

root@employees 10:54:31>select left("abcdef",3);              #从左边弹出指定长度字符串
+------------------+
| left("abcdef",3) |
+------------------+
| abc |
+------------------+
1 row in set (0.00 sec) root@employees 10:56:05>select right("abcdef",3); #从右边弹出指定长度字符串
+-------------------+
| right("abcdef",3) |
+-------------------+
| def |
+-------------------+
1 row in set (0.00 sec)

填充字符串函数

root@employees 11:00:23>select "abc", lpad("abc", 6, "defgh"), rpad("abc", 6, "defgh");                #填充的长度超过要求的长度则截断
+-----+-------------------------+-------------------------+
| abc | lpad("abc", 6, "defgh") | rpad("abc", 6, "defgh") |
+-----+-------------------------+-------------------------+
| abc | defabc | abcdef |
+-----+-------------------------+-------------------------+
1 row in set (0.00 sec) root@employees 11:00:45>select "abc", lpad("abc", 6, "d"), rpad("abc", 6, "d"); #填充的长度不足要求的长度则重复补充
+-----+---------------------+---------------------+
| abc | lpad("abc", 6, "d") | rpad("abc", 6, "d") |
+-----+---------------------+---------------------+
| abc | dddabc | abcddd |
+-----+---------------------+---------------------+
1 row in set (0.00 sec) root@employees 11:00:57>

删除指定字符串函数

trim(s1 from s)函数去掉字符s中开始处和结尾处的字符串s1.

root@employees 11:00:57>select trim("aa" from "aabcdefaaghiaaa");               #中间的满足的字符并不会被删除,
+-----------------------------------+
| trim("aa" from "aabcdefaaghiaaa") |
+-----------------------------------+
| bcdefaaghia |
+-----------------------------------+
1 row in set (0.00 sec) root@employees 11:04:47>select trim("a" from "aabcdefaaghiaaa");
+----------------------------------+
| trim("a" from "aabcdefaaghiaaa") |
+----------------------------------+
| bcdefaaghi |
+----------------------------------+
1 row in set (0.00 sec) root@employees 11:04:54>

重复和替换字符

root@employees 11:04:54>select repeat("a","5");                #字符“a”重复5次
+-----------------+
| repeat("a","5") |
+-----------------+
| aaaaa |
+-----------------+
1 row in set (0.00 sec) root@employees 11:06:49>select replace("shenyang","yang","zhen"); #“yang”替换为“zhen”
+-----------------------------------+
| replace("shenyang","yang","zhen") |
+-----------------------------------+
| shenzhen |
+-----------------------------------+
1 row in set (0.00 sec) root@employees 11:07:33>

MAKE_SET函数

make-set(x,s1,s2,...)函数按x的二进制数从s1,s2,....,sn中选取字符串。例如x值为12,二进制数为1100,这个二进制数从右到左的第三位和第四位是1,所有选取s3和s4.

root@employees 11:21:33>select make_set(11,"a","b","c","d"), make_set(3,"a","b","c","d");
+------------------------------+-----------------------------+
| make_set(11,"a","b","c","d") | make_set(3,"a","b","c","d") |
+------------------------------+-----------------------------+
| a,b,d | a,b |
+------------------------------+-----------------------------+
1 row in set (0.00 sec) #在计数时注意二进制数从低位到高位,字符串则按正常顺序。

EXPORT_SET函数

语法结构如下:

EXPORT_SET(bits,on,off[,separator[,number_of_bits]])

number_of_bits:默认数值是64,可以指定。
on的字符串对应1,off的字符串对应0.

通过一个实例来说明这个函数的用法:

root@employees 11:33:06>select export_set("11","a","b", "-", 6);
+----------------------------------+
| export_set("11","a","b", "-", 6) |
+----------------------------------+
| a-a-b-a-b-b |
+----------------------------------+
1 row in set (0.00 sec) root@employees 11:33:43> #数字11的二进制数为1011,把这个二进制数补全到number_of_bits位,这里是补全到6位即:001011,默认是64位。
然后数字1对应on位置的字符串即为a,数字0对应off位置的字符串即为b,然后按照二进制数的从低位到高位组成字符串即: aababb.最后把组成的字符串使用"-"连接即为:a-a-b-a-b-b

日期函数

日期函数也是用的比较多的函数,下面会详细介绍mysql中日期函数的用法。

获取当前日期和时间的函数

CURDATE()和CURRENT_DATE()函数获取当前日期;CURTIME()和CURRENT_TIME()获取当前时间。

root@employees 11:40:16>select curdate(),current_date(),curtime(),current_time();
+------------+----------------+-----------+----------------+
| curdate() | current_date() | curtime() | current_time() |
+------------+----------------+-----------+----------------+
| 2019-04-28 | 2019-04-28 | 23:42:31 | 23:42:31 |
+------------+----------------+-----------+----------------+
1 row in set (0.00 sec)

NOW(),CURRENT_TIMESTAMP(),LOCALTIME()和SYSDATE()等4个函数都用来获取当前的日期和时间。这四个函数标识相同的含义。

root@employees 11:42:31>select now(),current_timestamp(),localtime(),sysdate();
+---------------------+---------------------+---------------------+---------------------+
| now() | current_timestamp() | localtime() | sysdate() |
+---------------------+---------------------+---------------------+---------------------+
| 2019-04-28 23:45:11 | 2019-04-28 23:45:11 | 2019-04-28 23:45:11 | 2019-04-28 23:45:11 |
+---------------------+---------------------+---------------------+---------------------+
1 row in set (0.00 sec)

一个如下实例:

root@employees 11:47:23>select now(),current_timestamp(),localtime(),sysdate(), sleep(2), now(),current_timestamp(),localtime(),sysdate();
+---------------------+---------------------+---------------------+---------------------+----------+---------------------+---------------------+---------------------+---------------------+
| now() | current_timestamp() | localtime() | sysdate() | sleep(2) | now() | current_timestamp() | localtime() | sysdate() |
+---------------------+---------------------+---------------------+---------------------+----------+---------------------+---------------------+---------------------+---------------------+
| 2019-04-28 23:47:50 | 2019-04-28 23:47:50 | 2019-04-28 23:47:50 | 2019-04-28 23:47:50 | 0 | 2019-04-28 23:47:50 | 2019-04-28 23:47:50 | 2019-04-28 23:47:50 | 2019-04-28 23:47:52 |
+---------------------+---------------------+---------------------+---------------------+----------+---------------------+---------------------+---------------------+---------------------+
1 row in set (2.00 sec) root@employees 11:47:52>

可以看到最后一个sysdate返回的时间比其余的函数返回的时间差了2秒,其余函数返回的是语句执行时候的时间,而sysdate返回的则是语句执行到这个点的时间。

时间戳函数

有返回时间戳的函数,自然有转换时间戳的函数。UNIX_TIMESTAMP函数以时间戳的形式返回当前时间;unix_timestamp(d)函数将时间d以unxi时间戳的形式返回;from_unixtime(d)函数把时间戳转换为普通格式的时间。

root@employees 11:56:56>select now(),unix_timestamp(), unix_timestamp(now()), from_unixtime(unix_timestamp());
+---------------------+------------------+-----------------------+---------------------------------+
| now() | unix_timestamp() | unix_timestamp(now()) | from_unixtime(unix_timestamp()) |
+---------------------+------------------+-----------------------+---------------------------------+
| 2019-04-28 23:57:42 | 1556510262 | 1556510262 | 2019-04-28 23:57:42 |
+---------------------+------------------+-----------------------+---------------------------------+
1 row in set (0.00 sec) #unix_timestamp默认返回当前时间点的时间戳,也可以给一个时间参数,返回对应时间的时间戳。from_unixtime则把时间戳转换为对应的可读的时间。

返回UTC时间

UTC_DATE()函数返回UTC日期;UTC_TIME()函数返回UTC时间。UTC也就是国际日期协调时间。会有时区的差别的。

root@employees 11:57:42>select curdate(),utc_date(),curtime(),utc_time();
+------------+------------+-----------+------------+
| curdate() | utc_date() | curtime() | utc_time() |
+------------+------------+-----------+------------+
| 2019-04-29 | 2019-04-29 | 00:00:50 | 04:00:50 |
+------------+------------+-----------+------------+
1 row in set (0.00 sec)

与年月日和周相关的几个函数

MONTH(d)函数返回日期d中的月份,其取值范围是1~12;monthname(d)函数返回日期d中的月份的英文名称。

root@employees 12:01:11>select now(),month(now()),monthname(now());
+---------------------+--------------+------------------+
| now() | month(now()) | monthname(now()) |
+---------------------+--------------+------------------+
| 2019-04-29 01:48:29 | 4 | April |
+---------------------+--------------+------------------+
1 row in set (0.00 sec) root@employees 01:48:29>

dayname(d)函数返回日期d是星期几,显示英文名。dayofweek函数一周中的第几天,1表示第一天,2表示第二天(周日算第一天)。weekday返回日期是星期几,0表示星期一,1表示星期二。

root@employees 01:48:29>select dayname(now()),dayofweek(now()),weekday(now());         #星期一,一周中的第2天。
+----------------+------------------+----------------+
| dayname(now()) | dayofweek(now()) | weekday(now()) |
+----------------+------------------+----------------+
| Monday | 2 | 0 |
+----------------+------------------+----------------+
1 row in set (0.00 sec) root@employees 01:51:45>

获取周的函数week,以及一年中的第几周的函数。      #这两个值不一样,有点不理解?

root@employees 01:51:45>select week(now()),weekofyear(now());
+-------------+-------------------+
| week(now()) | weekofyear(now()) |
+-------------+-------------------+
| 17 | 18 |
+-------------+-------------------+
1 row in set (0.00 sec)

获取天数的函数

root@employees 01:57:32>select dayofyear(now()),dayofmonth(now()),now();
+------------------+-------------------+---------------------+
| dayofyear(now()) | dayofmonth(now()) | now() |
+------------------+-------------------+---------------------+
| 119 | 29 | 2019-04-29 01:57:45 |
+------------------+-------------------+---------------------+
1 row in set (0.00 sec) root@employees 01:57:45>

获取年份,季度,小时,分钟和秒钟的函数。

root@employees 01:57:45>select now(),year(now()),quarter(now()),minute(now()),second(now());
+---------------------+-------------+----------------+---------------+---------------+
| now() | year(now()) | quarter(now()) | minute(now()) | second(now()) |
+---------------------+-------------+----------------+---------------+---------------+
| 2019-04-29 01:59:25 | 2019 | 2 | 59 | 25 |
+---------------------+-------------+----------------+---------------+---------------+
1 row in set (0.00 sec)

获取日期的指定函数值

extract(type from d)函数从日期d中获取指定的值。这个值是什么由type的值决定。type的值可以是year,month,day,hour,minute和second。

root@(none) 03:08:14>select now(), extract(year from now());
+---------------------+--------------------------+
| now() | extract(year from now()) |
+---------------------+--------------------------+
| 2019-04-29 03:08:24 | 2019 |
+---------------------+--------------------------+
1 row in set (0.00 sec) root@(none) 03:08:24>

时间和秒钟的转换函数

time_to_sec(t)函数将时间t转换为以秒为单位的时间;sec_to_time(s)函数将以秒为单位的时间转换为时分秒的格式。

root@(none) 03:12:11>select curtime(),time_to_sec(curtime()),sec_to_time(11531);
+-----------+------------------------+--------------------+
| curtime() | time_to_sec(curtime()) | sec_to_time(11531) |
+-----------+------------------------+--------------------+
| 03:12:35 | 11555 | 03:12:11 |
+-----------+------------------------+--------------------+
1 row in set (0.00 sec)

计算日期和时间的函数

1:TO_DAYS(d),FROM_DAYS(N),DATEDIFF(d1,d2)函数。to_days函数计算日期d与0000年1月1日的天数;FROM_DAYS函数计算从0000年1月1日开始n天后的日期;DATEDIFF(d1,d2)函数计算两个日期的相隔天数。

root@(none) 03:12:35>select curdate(),to_days(curdate());
+------------+--------------------+
| curdate() | to_days(curdate()) |
+------------+--------------------+
| 2019-04-29 | 737543 |
+------------+--------------------+
1 row in set (0.00 sec) root@(none) 03:16:47>select from_days(737543);
+-------------------+
| from_days(737543) |
+-------------------+
| 2019-04-29 |
+-------------------+
1 row in set (0.00 sec) root@(none) 03:17:33>select datediff(curdate(), "2019-04-20");
+-----------------------------------+
| datediff(curdate(), "2019-04-20") |
+-----------------------------------+
| 9 |
+-----------------------------------+
1 row in set (0.00 sec)

2:adddate在指定的日期上加上n天,subdate在指定的日期上减去n天;addtime在指定的日期上加上n秒,subtime在指定的日期上减去n秒。

root@testdb 03:30:58>select curdate(),adddate(curdate(),3),subdate(curdate(),3);
+------------+----------------------+----------------------+
| curdate() | adddate(curdate(),3) | subdate(curdate(),3) |
+------------+----------------------+----------------------+
| 2019-04-29 | 2019-05-02 | 2019-04-26 |
+------------+----------------------+----------------------+
1 row in set (0.00 sec) root@testdb 03:31:07>

adddate的进阶用法:

ADDDATE(date,INTERVAL expr unit)函数和DATE_ADD(date,INTERVAL expr unit)函数,给日期的某一部分加上expr的时间。

root@testdb 04:04:30>select curdate(), adddate(curdate(),interval '' year);            #给当前日期的年份加上1
+------------+--------------------------------------+
| curdate() | adddate(curdate(),interval '' year) |
+------------+--------------------------------------+
| 2019-04-29 | 2020-04-29 |
+------------+--------------------------------------+
1 row in set (0.00 sec) root@testdb 04:04:45>
root@testdb 04:05:53>select curdate(), date_add(curdate(),interval '1 2' year_month); #给年份和月份分别加上1和2
+------------+-----------------------------------------------+
| curdate()  | date_add(curdate(),interval '1 2' year_month) |
+------------+-----------------------------------------------+
| 2019-04-29 | 2020-06-29                                    |
+------------+-----------------------------------------------+
1 row in set (0.00 sec) root@testdb 04:06:11

unit的间隔类型可以取值如下:

year, month, day, hour,minute, second, year_month, day_hour, day_minute, day_second, hour_minute, hour_second, minute_second

有加自然有减,对应的subdate的用法和上面一样。

将日期和时间格式化的函数

DATE_FORMAT(d,f)函数安装表达式f的要求显示日期d。表达式f指定来显示的格式。

root@testdb 04:06:11>select curdate(),date_format(curdate(),"%b %D %Y");
+------------+-----------------------------------+
| curdate() | date_format(curdate(),"%b %D %Y") |
+------------+-----------------------------------+
| 2019-04-29 | Apr 29th 2019 |
+------------+-----------------------------------+
1 row in set (0.00 sec)

time_formate(d,f)按照响应的格式显示时间。

格式化的时候不同的简写代表不同格式,具体内容可以参考官方文档:https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_date-format

其他函数

格式化函数

format(x,n)函数可以将数字x进行格式化,将x保留到小数点后n位,这个过程需要四舍五入。

root@testdb 04:20:18>select format(3.14159, 3);
+--------------------+
| format(3.14159, 3) |
+--------------------+
| 3.142 |
+--------------------+
1 row in set (0.00 sec)

ip地址与数字相互转换

inet_aton(ip)函数可以将ip地址转换为数字表示;inet_ntoa(n)函数可以将数字转换为ip形式。

root@testdb 04:20:20>select inet_aton("10.0.68.42");
+-------------------------+
| inet_aton("10.0.68.42") |
+-------------------------+
| 167789610 |
+-------------------------+
1 row in set (0.00 sec) root@testdb 04:22:33>select inet_ntoa(167789610);
+----------------------+
| inet_ntoa(167789610) |
+----------------------+
| 10.0.68.42 |
+----------------------+
1 row in set (0.00 sec) root@testdb 04:22:49>

重复执行操作的函数

benchmark(count,expr)函数将表达式expr重复执行count次,然后返回执行时间。

root@testdb 04:26:33>select benchmark(10000,now());            #这说明执行时间短,为0
+------------------------+
| benchmark(10000,now()) |
+------------------------+
| 0 |
+------------------------+
1 row in set (0.00 sec) root@testdb 04:26:56>
root@testdb 04:25:59>select benchmark(2,sleep(2)); #这个4秒的时间,不知道为啥也是0
+-----------------------+
| benchmark(2,sleep(2)) |
+-----------------------+
| 0 |
+-----------------------+
1 row in set (4.00 sec)

改变字段数据类型的函数

cast(x as type)和convert(x, type)这两个函数将x变成type类型,这两个函数只对binary,char,date,datetime,time,int这些类型起作用。只改变来输出值的数据类型,不改变表中字段的类型。

root@testdb 04:26:56>select now(), cast(now() as date),convert(now(),time);
+---------------------+---------------------+---------------------+
| now() | cast(now() as date) | convert(now(),time) |
+---------------------+---------------------+---------------------+
| 2019-04-29 04:31:26 | 2019-04-29 | 04:31:26 |
+---------------------+---------------------+---------------------+
1 row in set (0.00 sec)
上一篇:golang中字符串内置函数整理


下一篇:javascript中的内置对象