函数这个概念可以追溯到高中。例如:y=f(x)这就是一个函数。在Mysql中大体有如下几类重要的函数。分组函数、数学函数、字符串函数、日期时间函数、流程控制语句函数、加密函数、窗口函数等。从程序员角度的看,就是Mysql提供的一些常用的有入参和返回值的方法。函数一般都有输入值,然后有返回值。
接下来开始,复习一下分组函数,分组函数多行一起统计或合计运算一个结果值sum,count,avg,max,min都是针对多行求一个结果。以下是单行函数,一行运算一个结果值。具体的实例:
ROUND(X,Y):小数点后取y位,并且四舍五入
----先创建学生成绩表CREATE TABLE `student_score` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',`student_id` bigint(20) DEFAULT NULL COMMENT '学生ID',`course_id` bigint(20) DEFAULT NULL COMMENT '科目ID',`score` decimal(10,2) NOT NULL COMMENT '分数',PRIMARY KEY (`id`) USING BTREE,KEY `student_id` (`student_id`),KEY `course_id` (`course_id`)) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COMMENT='学生成绩表';insert into `student_score`(`id`,`student_id`,`course_id`,`score`) values(1,1,1,50.55),(4,4,1,75.65);--ROUND(X,Y):小数点后取y位,并且四舍五入--TRUNCATE(X,Y):直接截掉,保留x的小数点后取y位--查询学员成绩,保留一位整数SELECT student_id, ROUND(score,1) AS round_, TRUNCATE(score,1) AS truncate_ FROM `student_score`;
字符串相关函数
以上这些了解一下即可。接下来看一下字符串函数。这个就比较重要了,工作中清洗数据时,会常用以下函数。具体实列如下:
CREATE TABLE `student` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '学生ID',`name` varchar(20) DEFAULT NULL COMMENT '学生ID',`age` int(10) DEFAULT NULL COMMENT '学生年龄',`sex` char(1) DEFAULT NULL COMMENT '性别:0女|1男',PRIMARY KEY (`id`) USING BTREE) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COMMENT='学生信息表';insert into `student`(`id`,`name`,`sex`) values(1,'郭德纲',10,'1'),(2,'宋丹丹',12,'0'),(3,'宋茜',8,'1'),(4,'蒋方舟',3,'0');1.查询每个学员的姓氏SELECT NAME AS "姓名", LEFT(NAME,1) AS "姓" FROM student;SELECT NAME AS "姓名", SUBSTRING(NAME,1,1) AS "姓" FROM student;2.查询学生的姓名的长度SELECT NAME, LENGTH(NAME) FROM student;SELECT NAME, CHAR_LENGTH(NAME) FROM student;3.查询所有名字是2个字的学生SELECT * FROM student WHERE CHAR_LENGTH(NAME) = 2;4.查询学员的姓名和性别,结果要显示为:张三:男SELECT CONCAT(name,':',sex) FROM student;SELECT INSERT('我爱编程helloworld',1,2,'超级热爱'); /*替换字符串,从某个位置开始替换某个长度*/SELECT LOWER('KuangShen'); /*小写*/SELECT UPPER('KuangShen'); /*大写*/SELECT LEFT('hello,world',5); /*从左边截取*/SELECT RIGHT('hello,world',5); /*从右边截取*/SELECT REPLACE('狂神说坚持就能成功','坚持','努力'); /*替换字符串*/SELECT SUBSTR('狂神说坚持就能成功',4,6); /*截取字符串,开始和长度*/SELECT REVERSE('狂神说坚持就能成功'); /*反转
时间函数
| 函数 | 描述 |
|---|---|
| NOW() | 返回当前的日期和时间 |
| CURDATE() | 返回当前的时间 |
| DATE() | 提取日期或日期/时间表达式的日期部分 |
| EXTRACT() | 返回日期/时间的单独部分 |
| DATE_ADD() | 向日期添加指定的时间间隔 |
| DATE_SUB() | 从日期减去指定的时间间隔 |
| DATEDIFF() | 返回两个日期之间的天数 |
| DATE_FORMAT() | 用不同的格式显示日期/时间 |
SELECT CURRENT_DATE(); /*获取当前日期*/SELECT CURDATE(); /*获取当前日期*/SELECT NOW(); /*获取当前日期和时间*/SELECT LOCALTIME(); /*获取当前日期和时间*/SELECT SYSDATE(); /*获取当前日期和时间*/-- 获取年月日,时分秒SELECT YEAR(NOW());SELECT MONTH(NOW());SELECT DAY(NOW());SELECT HOUR(NOW());SELECT MINUTE(NOW());SELECT SECOND(NOW());
时间加减运算:常用时间类型有SECOND、MINUTE、HOUR、DAY、WEEK、MONTH、QUARTER、YEAR,更多
1.加一段时间DATE_ADD(create_time,INTERVAL 20 minute) // 加20分钟DATE_ADD(#{endEndPlanTime},INTERVAL 1 DAY) // 加1天2.减一段时间DATE_SUB(now(),INTERVAL 1 DAY) // 减1天DATE_SUB(now(),INTERVAL 1 MONTH) // 减1个月
按照时间统计可能用到的sql语法:
--今天的数据select * from 表名 where TO_DAYS(create_time) = TO_DAYS(now());--当前时间前一天SELECT * FROM 表名 WHERE TO_DAYS(NOW()) - TO_DAYS(create_time) <= 1--昨天SELECT * FROM 表名 WHERE DATE_FORMAT(DATE_SUB(now(),INTERVAL 1 DAY),'%Y-%m-%d')--本周(默认周日为第一天)SELECT * FROM 表名 WHERE YEARWEEK( date_format( create_time, '%Y-%m-%d' ) ) = YEARWEEK(now()) ;--本周(设置周一为第一天) YEARWEEK( now(), n )SELECT * FROM 表名 WHERE YEARWEEK( date_format( create_time, '%Y-%m-%d' ) ) = YEARWEEK(now(), 1) ;--本月SELECT * FROM 表名 WHERE DATE_FORMAT(create_time, '%Y%m' ) = DATE_FORMAT( CURDATE() ,'%Y%m' ) ;--上一月SELECT * FROM 表名 WHERE PERIOD_DIFF( date_format( now() , '%Y%m' ) , date_format( create_time, '%Y%m' ) ) =1 ;SELECT * FROM 表名 WHERE date_format(create_time,'%Y-%m')=date_format(DATE_SUB(curdate(), INTERVAL 1 MONTH),'%Y-%m') ;--本季度数据select * from 表名 where QUARTER(create_time)=QUARTER(now());--上季度数据select * from 表名` where QUARTER(create_time)=QUARTER(DATE_SUB(now(),interval 1 QUARTER));--本年SELECT * FROM 表名 WHERE YEAR( create_time ) = YEAR( NOW() )
自动补0的统计查询sql
---- 按天统计某段时间内的数据,没有的自动补0
SELECT date_format(a.date, '%Y-%m-%d') AS "date"
, (
SELECT count(1)
FROM order b
WHERE a.date = date_format(b.pay_time, '%Y-%m-%d')
) AS "count"
FROM (
SELECT @cdate := DATE_ADD(@cdate, INTERVAL -1 DAY) AS `date`
FROM (
SELECT @cdate := DATE_ADD(#{endDate}, INTERVAL +1 DAY)
FROM `sys_menu`
) d1
WHERE @cdate > #{beginDate}
) a
---- 统计当前月每天数据,没有自动补0
SELECT date_format(a.date, '%Y-%m-%d') AS "date"
, (
SELECT count(*)
FROM order b
WHERE a.date = date_format(b.pay_time, '%Y-%m-%d')
) AS "count"
FROM (
SELECT @cdate := DATE_ADD(@cdate, INTERVAL -1 DAY) AS `date`
FROM (
SELECT @cdate := DATE_ADD(CURDATE(), INTERVAL +1 DAY)
FROM `sys_menu`
) d1
WHERE YEAR(@cdate) = YEAR(CURDATE())
AND MONTH(@cdate) = MONTH(CURDATE())
AND DAY(@cdate) > 1
) a
---- 统计近一年每个月的数据,没有的自动补0 近n天、n月的同理
SELECT b.date AS "date"
, (
SELECT count(1)
FROM order a
WHERE a.del_flag = '0'
AND DATE_FORMAT(a.create_time, '%Y-%m') = b.date
) AS "count"
FROM (
SELECT DATE_FORMAT(now(), '%Y-%m') AS date
UNION
SELECT DATE_FORMAT(DATE_SUB(now(), INTERVAL 1 MONTH), '%Y-%m') AS date
UNION
SELECT DATE_FORMAT(DATE_SUB(now(), INTERVAL 2 MONTH), '%Y-%m') AS date
UNION
SELECT DATE_FORMAT(DATE_SUB(now(), INTERVAL 3 MONTH), '%Y-%m') AS date
UNION
SELECT DATE_FORMAT(DATE_SUB(now(), INTERVAL 4 MONTH), '%Y-%m') AS date
UNION
SELECT DATE_FORMAT(DATE_SUB(now(), INTERVAL 5 MONTH), '%Y-%m') AS date
UNION
SELECT DATE_FORMAT(DATE_SUB(now(), INTERVAL 6 MONTH), '%Y-%m') AS date
UNION
SELECT DATE_FORMAT(DATE_SUB(now(), INTERVAL 7 MONTH), '%Y-%m') AS date
UNION
SELECT DATE_FORMAT(DATE_SUB(now(), INTERVAL 8 MONTH), '%Y-%m') AS date
UNION
SELECT DATE_FORMAT(DATE_SUB(now(), INTERVAL 9 MONTH), '%Y-%m') AS date
UNION
SELECT DATE_FORMAT(DATE_SUB(now(), INTERVAL 10 MONTH), '%Y-%m') AS date
UNION
SELECT DATE_FORMAT(DATE_SUB(now(), INTERVAL 11 MONTH), '%Y-%m') AS date
) b
ORDER BY date
其他日期函数:
通过date_format函数查看某个日期是星期几
mysql> select date_format('2018-06-26','%W'); #%W(大写W),查看出来的是日期所在的星期,英文的全写Tuesday
+--------------------------------+
| date_format('2018-06-26','%W') |
+--------------------------------+
| Tuesday |
+--------------------------------+
mysql> select date_format('2018-06-26','%a'); #%a返回的是日期所在的星期英文的简写,Tue,注意:Abbreviated=a,简短的
+--------------------------------+
| date_format('2018-06-26','%a') |
+--------------------------------+
| Tue |
+--------------------------------+
通过周函数查看某个日期是星期几
mysql> select DAYOFWEEK(CURRENT_TIMESTAMP()); #返回日期date的星期索引(1=星期天,2=星期一, ……7=星期六)。这些索引值对应于ODBC标准。
+--------------------------------+
| DAYOFWEEK(CURRENT_TIMESTAMP()) |
+--------------------------------+
|3 |
+--------------------------------+
mysql> select WEEKDAY(CURRENT_TIMESTAMP()); #返回date的星期索引(0=星期一,1=星期二, ……6= 星期天)
+------------------------------+
| WEEKDAY(CURRENT_TIMESTAMP()) |
+------------------------------+
|1 |
+------------------------------+
更多函数关注 MySQL菜鸟教程 、SQL教程
小结
-- ================ 内置函数 ================
-- 数值函数
abs(x) -- 绝对值 abs(-10.9) = 10
format(x, d) -- 格式化千分位数值 format(1234567.456, 2) = 1,234,567.46
ceil(x) -- 向上取整 ceil(10.1) = 11
floor(x) -- 向下取整 floor (10.1) = 10
round(x) -- 四舍五入去整
mod(m, n) -- m%n m mod n 求余 10%3=1
pi() -- 获得圆周率
pow(m, n) -- m^n
sqrt(x) -- 算术平方根
rand() -- 随机数
truncate(x, d) -- 截取d位小数
-- 时间日期函数
now(), current_timestamp(); -- 当前日期时间
current_date(); -- 当前日期
current_time(); -- 当前时间
date('yyyy-mm-dd hh:ii:ss'); -- 获取日期部分
time('yyyy-mm-dd hh:ii:ss'); -- 获取时间部分
date_format('yyyy-mm-dd hh:ii:ss', '%d %y %a %d %m %b %j'); -- 格式化时间
unix_timestamp(); -- 获得unix时间戳
from_unixtime(); -- 从时间戳获得时间
-- 字符串函数
length(string) -- string长度,字节
char_length(string) -- string的字符个数
substring(str, position [,length]) -- 从str的position开始,取length个字符
replace(str ,search_str ,replace_str) -- 在str中用replace_str替换search_str
instr(string ,substring) -- 返回substring首次在string中出现的位置
concat(string [,...]) -- 连接字串
charset(str) -- 返回字串字符集
lcase(string) -- 转换成小写
left(string, length) -- 从string2中的左边起取length个字符
load_file(file_name) -- 从文件读取内容
locate(substring, string [,start_position]) -- 同instr,但可指定开始位置
lpad(string, length, pad) -- 重复用pad加在string开头,直到字串长度为length
ltrim(string) -- 去除前端空格
repeat(string, count) -- 重复count次
rpad(string, length, pad) --在str后用pad补充,直到长度为length
rtrim(string) -- 去除后端空格
strcmp(string1 ,string2) -- 逐字符比较两字串大小
-- 聚合函数
count()
sum();
max();
min();
avg();
group_concat()
-- 其他常用函数
md5();
default();
