1、函数的作用
函数可以把我们经常使用的代码封装起来,需要时直接调用即可
这样既提高了代码效率
,又提高了代码可维护性
在SQL中我们也可以使用函数对检索出来的数据进行操作,极大提高用户对数据库的管理效率
2、函数的分类
分为内置函数
和自定义函数
3、MySQL内置函数的分类
从功能角度可以分为数值函数、字符串函数、日期和时间函数、流程控制函数、加密和解密函数、获取MySQL信息函数、聚合函数等
也可以只分为单行函数和聚合函数(分组函数)
SELECT ABS(-123),ABS(32),SIGN(-23),SIGN(32),PI() FROM DUAL;
SELECT CEIL(-32.2),CEILING(32.2),FLOOR(-32.2),FLOOR(32.2),MOD(12,5) FROM DUAL;
SELECT LEAST(1,7,3),GREATEST(1,7,3) FROM DUAL;
SELECT RAND(),RAND(),RAND(10),RAND(10) FROM DUAL;
SELECT ROUND(12.256,0),ROUND(12.256,2),ROUND(12.256,-1) FROM DUAL;
SELECT TRUNCATE(12.256,0),TRUNCATE(12.256,-1),TRUNCATE(12.256,2) FROM DUAL;
SELECT SQRT(4) FROM DUAL;
SELECT TRUNCATE(ROUND(12.2345,3),2); # 单行函数可以嵌套
包括正弦、余弦、正切等函数,因为博主在工作中遇到的场景不多,所以这里就简单了解一下就行
SELECT POWER(2,2),POWER(2,-2),EXP(1),
LN(2.718281828459045),LOG(2.718281828459045),
LOG10(10),LOG2(2) FROM DUAL;
SELECT BIN(10),HEX(12),OCT(8),CONV(10,2,8) FROM DUAL;
注意:MySQL中字符串的下标都是从1开始的
SELECT ASCII('a'),CHAR_LENGTH('hello'),CHAR_LENGTH('你好'),LENGTH('hello'),LENGTH('你好')
FROM DUAL;
SELECT CONCAT('hello','world'),CONCAT_WS('-','hello','world','LOL'),
INSERT('hello',2,2,'aaaa') FROM DUAL;
SELECT REPLACE('helloworld','l','s'),UPPER('aa'),LOWER('BB'),
LEFT('hello',2),RIGHT('world',2) FROM DUAL;
SELECT LPAD('hello',8,'*'),RPAD('world',8,'---'),LENGTH(LTRIM(' hello ')) FROM DUAL;
SELECT LENGTH(RTRIM(' hello ')),LENGTH(TRIM(' hello ')),TRIM('o' FROM 'ollo'),
TRIM(LEADING 'o' FROM 'oolo'),TRIM(TRAILING 'o' FROM 'laoo')
FROM DUAL;
SELECT REPEAT('asa',3),CONCAT('hello',SPACE(3),'world'),
STRCMP('abc','abe'),STRCMP('abc','aba') FROM DUAL;
SELECT SUBSTR('world',2,3),LOCATE('worldaaa','a'),ELT(2,'aa','bb','cc','dd'),
FIELD('aa','sd','wqas'),FIELD('aa','sd','aa'),
FIND_IN_SET('a','sd,as'),FIND_IN_SET('as','sd,as') FROM DUAL;
SELECT REVERSE('asdf'),NULLIF('aa','bb')
FROM DUAL;
下面是一些常用的日期时间函数
# 获取日期、时间
SELECT CURRENT_TIME(),CURRENT_DATE(),CURDATE(),now() FROM DUAL;
# 日期与时间戳的转换
SELECT UNIX_TIMESTAMP(),UNIX_TIMESTAMP('2022-12-12 12:00:00'),FROM_UNIXTIME(1679487187),FROM_UNIXTIME(1670817600) FROM DUAL;
# 获取年、月份、天数
SELECT YEAR(CURDATE()),MONTH(CURDATE()),DAY(CURDATE()) FROM DUAL;
# 获取星期几、周几(周一是0)、季度、第几周
SELECT DAYNAME(CURDATE()),WEEKDAY(CURDATE()),QUARTER(CURDATE()),WEEKOFYEAR(CURDATE()) FROM DUAL;
# 获取每年的第几天、每月的第几天、每周的第几天(周日是1)
SELECT DAYOFYEAR(CURDATE()),DAYOFMONTH(CURDATE()),DAYOFWEEK(CURDATE()) FROM DUAL;
# 获取距离目标时间的天数,或者与某个时间点的时间间隔
SELECT DATEDIFF(NOW(),'2022-01-01'),TIMEDIFF(NOW(),'2021-12-21 12:00:00') FROM DUAL;
# 日期的格式化与解析
# 格式化:日期-->字符串 DATE_FORMAT(date,fmt)和TIME_FORMAT(date,fmt),fmt表示要格式化成什么样的格式
SELECT DATE_FORMAT(CURDATE(),'%Y-%m-%d'),DATE_FORMAT(NOW(),'%Y-%m-%d %H:%i:%S'),TIME_FORMAT(NOW(),'%H:%i:%S') FROM DUAL;
# 解析: 字符串-->日期,STR_TO_DATE(str,fmt),按照ftm格式对字符串str进行逆向转换
SELECT STR_TO_DATE('2023-03-22','%Y-%m-%d %H:%i:%S');
# 获取想要的格式,GET_FORMAT(date_type,format_type),比如想获取满足IOS标准的日期,data_type就是DATE,format_type就是ISO
SELECT GET_FORMAT(DATE, 'ISO'),DATE_FORMAT(CURDATE(),GET_FORMAT(DATE, 'ISO')) FROM DUAL;
流程控制函数一般分为顺序结构、分支结构和循环结构
其中代码从上往下执行就是顺序结构,SQL按行处理数据就是循环遍历
下面我们介绍一下分支结构
IF(value,value1,value2)
:如果value判断为true,则返回value1,否则返回value2IFNULL(value1,value2)
:如果value1不为null,则返回value1,否则就返回value2CASE WHEN 条件1 THEN 结果1 WHEN 条件2 THEN 结果2...ELSE 结果n END
:相当于Java语言中的if…else if…else。注意这里和Java一样,最后兜底的那个ELSE可以不要,那些没有被兜底的字段数就显示nullCASE 表达式expr WHEN 常量值1 THEN 值1 WHEN 常量值2 THEN 值2...ELSE 值n END
:相当于Java语言中的switch…case…,同上,最后兜底的那个ELSE可以不要,那些没有被兜底的字段数就显示null我们先创建一个blog表,插入一些数据以便使用
DROP TABLE IF EXISTS `t_decade_blog`;
CREATE TABLE `t_decade_blog` (
`id` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '博客id',
`name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '博客名称',
`author` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '博客作者',
`create_time` datetime(0) NOT NULL COMMENT '创建时间',
`views` int(20) NOT NULL COMMENT '博客浏览量'
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
INSERT INTO `t_decade_blog` VALUES ('76782763-48d0-4cef-b8e1-1054e181e41d', 'Mybatis系列', 'Decade0712', '2022-03-28 22:30:14', 2000);
INSERT INTO `t_decade_blog` VALUES ('06bd6c69-e47e-4e78-9e02-5110a013e457', 'Spring系列', 'Decade0712', '2022-03-28 22:30:14', 4000);
INSERT INTO `t_decade_blog` VALUES ('d3258b79-d543-49bb-9850-16cac7565f57', '设计模式系列', 'Decade0712', '2022-03-28 22:30:14', 6000);
然后我们使用上方的流程函数做一些查询操作
SELECT name,views,IF(views>2000,'浏览量不足2000','浏览量让人满意') result
FROM t_decade_blog;
SELECT name,views,IFNULL('有人浏览','没人浏览') result
FROM t_decade_blog;
SELECT name,views,CASE WHEN views=2000 THEN'初级浏览量'
WHEN views=4000 THEN '中级浏览量'
ELSE '高级浏览量或者没人浏览'
END result
FROM t_decade_blog;
SELECT name,views,CASE WHEN views=2000 THEN'初级浏览量'
WHEN views=4000 THEN '中级浏览量'
END result
FROM t_decade_blog;
SELECT name,views,CASE views
WHEN 2000 THEN '初级浏览量'
WHEN 4000 THEN '中级浏览量'
ELSE '高级浏览量或者没人浏览'
END result
FROM t_decade_blog;
SELECT name,views,CASE views
WHEN 2000 THEN '初级浏览量'
WHEN 4000 THEN '中级浏览量'
END result
FROM t_decade_blog;
加密结果不可逆如何比较?
直接比较加密后的参数,相同的明文加密得到的结果是相同的
SELECT PASSWORD('mysql'),MD5('mysql'),MD5('mysql'),SHA('mysql') FROM DUAL;
SELECT DECODE(ENCODE(123,'mysql'),'mysql'),ENCODE(123,'mysql') FROM DUAL;
SELECT VERSION(),CONNECTION_ID(),DATABASE(),SCHEMA(),
USER(),CHARSET('十年'),COLLATION('十年') FROM DUAL;
SELECT FORMAT(123.356,2),CONV(100,10,2),INET_ATON('192.168.1.1'),INET_NTOA('3232235777') FROM DUAL;
SELECT BENCHMARK(800000,SHA('mysql')) FROM DUAL;
SELECT CHARSET('十年'),CHARSET(CONVERT('十年' USING 'utf8mb3')),CONVERT('十年' USING 'utf8mb4') FROM DUAL;
如有错误,欢迎指正!!!