前言
上一篇博客简单总结了一些mysql中常用的SQL语句,这一篇博客总结一下mysql中常用的函数,以及mysql8.0中新增的公共表达式等内容。mysql中常用的系统函数不多,主要分为时间系统函数,字符串系统函数以及一些其他的系统函数。
常用的时间函数
直接获取时间的函数
直接上表格
| 函数名称 | 说明 |
|---|---|
| CURDATE() | 返回当前日期 |
| CURTIME | 返回当前时间 |
| NOW() | 返回当前的日期和时间 |
| DATE_FORMAT(date,fmt) | 按照fmt的格式,对日期date进行格式化 fmt的格式——%Y:四位的年 %m:月份(00…12) %d:天(00…31) %H:小时(00…24) %i:分钟(00…59) %s秒(00…59) |
实例说明
SELECT CURDATE(),CURTIME(),NOW();
SELECT DATE_FORMAT(NOW(),'%Y-%m-%d %H-%i-%s');

时间计算函数
| 函数名称 | 说明 |
|---|---|
| SEC_TO_TIME(seconds) | 把秒数转换成为(小时:分:秒) |
| TIME_TO_SEC(time) | 把时间(小时:分:秒)转换为秒数 |
| DATEDIFF(date1,date2) | 返回date1和date2两个日期相差的天数 |
| DATE_ADD(date,INTEGER expr unit) | 对给定的日期增加或减少指定的时间单元(unit:DAY天/HOUR小时/MINUTES分钟/SECOND/秒) |
| EXTRACT(unit FROM date) | 返回日期date的指定部分 |
| UNIX_TIMESTAMP() | 返回unix的时间戳 |
| FROM_UNIXTIME() | 把unix时间戳转换为日期时间 |
实例
-- sec_to_time,time_to_sec,UNIX_TIMESTAMP,FROM_UNIXTIME
-- datediff,extract
SELECT SEC_TO_TIME(3600),TIME_TO_SEC('02:30:00')
,UNIX_TIMESTAMP('2021-12-03 15:45:22')
,FROM_UNIXTIME(1638517522)
,DATEDIFF('2022-02-03','2022-01-01')
,EXTRACT(YEAR FROM '2021-12-03');

-- date_add函数
SELECT NOW()
,DATE_ADD(NOW(),INTERVAL 1 DAY)-- 当前时间加一天
,DATE_ADD(NOW(),INTERVAL 1 YEAR) -- 当前时间加1年
,DATE_ADD(NOW(),INTERVAL -1 DAY) -- 当前时间减1天
,DATE_ADD(NOW(),INTERVAL '-1:30' HOUR_MINUTE) -- 当前时间减1:30
-- 计算每门课程距离当前时间的天数
SELECT title,DATEDIFF(NOW(),online_time)
FROM t_class_course;
常用的字符串函数
直接上表格
| 函数名称 | 说明 |
|---|---|
| CONCAT(str1,str2,…) | 将字符串str1,str2,…拼接成一个串 |
| CONCAT_WS(sep,str1,str2,…) | 用指定的分隔符拼接str1,str2… |
| CHAR_LENGTH(str) | 返回字符串str的字符个数 |
| LENGTH(str) | 返回字符串str的字节个数 |
| FORMAT(X,D[,locale]) | 将数字X格式化为指定的格式:"#,###,###.##",并舍入到D位小数 |
| LEFT(str,len) | 从字符串str的左边起,返回len长度的子字符串 |
| RIGHT(str,len) | 从字符串str的右边起,返回len长度的子字符串 |
| SUBSTRING(str,pos,[len]) | 从字符串str的pos位置起,返回长度为len的子串 |
| SUBSTRING_INDEX(str,delim,count) | 返回字符串str按delim分割的前count个字符串 |
| LOCATE(substr,str) | 返回substr第一次在str中出现的位置 |
| TRIM([remstr FROM] str) | 从字符串str两端删除不需要的字符remstr |
实例
-- 字符串拼接
SELECT CONCAT('prefix','subfix');
SELECT CONCAT_WS('||','prefix','subfix');
-- 字符长度
SELECT class_name,LENGTH(class_name),CHAR_LENGTH(class_name)
FROM imc_class
-- 指定四舍五入的小数位
SELECT FORMAT(12345.7896,3,'#');
-- 字符串截取
SELECT LEFT('www.mysql.learn',3),RIGHT('www.mysql.learn',5)
SELECT SUBSTRING('www.mysql.learn',5); -- 输出mysql.learn
SELECT SUBSTRING_INDEX('192.168.0.100','.',-2); -- 输出 0.100 从右边起第几个用负数表示
-- trim删除空格或者指定的字符
SELECT TRIM(' learnMySQL'),TRIM('j' FROM 'jjjjjjjLearnjjjjjjj');
-- 截取课程标题中横线之前的部分
SELECT title,LOCATE('-',title),SUBSTRING(title,1,LOCATE('-',title)-1)
FROM t_class_course
其他系统函数
表格
| 函数名称 | 说明 |
|---|---|
| ROUND(X,D) | 对数值X进行四舍五入保留D位小数 |
| RAND() | 返回一个在0和1之间的随机数 |
| CASE WHEN [condition] THEN result [WHEN [condition] THEN result …] [ELSE result] END | case…when,提供数据流程控制。 |
| MD5(str) | 返回str的MD5值 |
实例
-- case when 的实例
SELECT
user_nick,
CASE
WHEN sex = 1 THEN '男'
WHEN sex = 0 THEN '女'
ELSE '未知'
END AS '性别'
FROM
t_calss_user
-- case when在where中的使用
-- 在上面的基础上,查询出所有男性的用户信息
SELECT
user_nick,
CASE
WHEN sex = 1
THEN '男'
WHEN sex = 0
THEN '女'
ELSE '未知'
END AS '性别'
FROM
t_calss_user
WHERE
CASE
WHEN sex = 1
THEN '男'
WHEN sex = 0
THEN '女'
ELSE '未知'
END = '男'
公共表表达式
公共表表达式(Common Table Expression),简称CTE是mysql8.0中的新特性,个人认为这个是比子查询更好的一种查询方式,相比子查询,CTE会在查询的时候生成一个临时表,并且在查询的时候,可以多次引用以及自引用(递归引用)。其性能和可读性要比子查询好得多。
公共表表达式语法
WITH [RECURSIVE] -- 可以递归定义
cte_name [(column_list)] AS (
query
)
[,cte_name [(column_list)] as ( -- 可以同时定义多个
query
)]
-- 这个不能少
SELECT * FROM cte_name;
基础实例
-- 一个简单的公共表表达式
WITH cte AS(
SELECT title,study_cnt,class_id
FROM t_class_course
WHERE study_cnt > 200
)
SELECT * FROM cte;
-- 公共表表达式可以多次引用,而子查询是不行的
SELECT * FROM cte
UNION ALL
SELECT * FROM cte
ORDER BY title;
递归的公共表表达式实例
-- 公共表表达式递归生成自增序列
WITH recursive cte_test AS(
SELECT 1 AS n
UNION ALL
SELECT 1+n FROM cte_test -- 自己引用自己
WHERE n<10
)
SELECT * FROM cte_test;
执行结果
递归常用与树形结构数据的遍历,复杂的实例这里不再提供,这个基于不同的业务有不同的处理方式。
窗口函数
窗口函数也是mysql8.0以上的专属,窗口函数是相对于聚合函数而言的,聚合函数是将一组数据汇总为单个结果,而窗口函数是针对查询中的每一行数据,基于和它相关的一组数据计算出一个结果
这个可以参考这篇博客:掘金小册——窗口函数。
小结
mysql系统函数的简单总结
版权声明:本文为liman65727原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。