MySQL的函数

一.介绍

1.在MySQL中,为了提高代码重用性和隐藏实现细节,MySQL提供了很多函数。函数可以理解为别人封装好的模板代码。

2.分类:聚合函数,数学函数,字符串函数,日期函数,控制流函数,窗口函数

二:聚合函数

MySQL的函数_第1张图片

MySQL的函数_第2张图片

MySQL的函数_第3张图片三:数学函数 

MySQL的函数_第4张图片

MySQL的函数_第5张图片 MySQL的函数_第6张图片

-- 数学函数

-- 求绝对值
select abs(-10);               -- 10
select abs(10);                -- 10
select abs(表达式或者字段) from 表;

-- 向上取整
select ceil(1.1);              -- 2
select ceil(1.0);              -- 1
					 
-- 向下取整
select floor(1.1);             -- 1 
select floor(1.9);             -- 1
					 
-- 取列表最大值					 
select greatest(1,2,3);	       -- 3				 
					 
-- 取列表最小值					 
select least(1,2,3);	       -- 1			 
					 
-- 取模
select mod(5,2);               -- 1

-- 取x的y次方
select power(2,3);             -- 8
					 
-- 取随机数					 
select rand();		           -- 0.0005110669885865105 
					 
-- 将小数四舍五入取整					
select round(3.5415);          -- 4
select round(3.5415,3);        -- 保留三位小数  3.542

select category_id,round(avg(price),2) from product group by category_id;
					 
-- 将小数直接截取到指定位数					 
select truncate(3.1415,3);	   -- 3.141		

四:字符串函数

MySQL的函数_第7张图片

MySQL的函数_第8张图片 MySQL的函数_第9张图片

MySQL的函数_第10张图片

-- 字符串函数
 
-- 1.获取字符串字符个数					 
select char_length('hello');	         -- 5				 
select char_length('你好啊');		     -- 3			 
					 
-- length 取长度,返回的单位是字节					 
select length('hello');					 -- 5
select length('你好啊');				     -- 9	 
					 
-- 2.字符串合并					 
select concat('hello','world');
select concat(c1,c2) from table_name;

-- 3.指定分隔符进行字符串合并
select concat_ws('-','hello','world');-- hello-world

-- 4.返回字符串在列表中的位置
select field('aaa','aaa','bbb','ccc');   -- 1
select field('bbb','aaa','bbb','ccc');   -- 2
select field('aaa','aaa','aaa','bbb','ccc');   -- 1 返回在列表中第一次出现的位置

-- 5.去除字符串空格
select ltrim('    aaaa');               -- 去除左边空格
select rtrim('aaaa     ');              -- 去除右边空格
select trim('    aaaa    ');            -- 去除两边空格

-- 6.字符串截取
select mid('helloworld',2,3);          -- 从第二个字符开始截取,截取长度为3  ell

-- 7.获取字符串在另一个字符串中出现的位置
select position('abc' in 'habcelloabcworld');  -- 2 截取出现的第一个位置

-- 8.字符串替换
select replace('aaahelloaaaworld','aaa','bbb');-- bbbhellobbbworld

-- 9. 字符串翻转
select reverse('hello');           -- olleh

-- 10.返回字符串的后几个字符
select right('hello',3);           -- 返回后三个字符 llo

-- 11.字符串比较
select strcmp('hello','world');    -- -1

-- 12.字符串截取
select substr('hello',2,3);        -- 从第二个字符开始截取,截取长度为3  ell

-- 13.将小写转化为大写
select ucase('helloworld');
select upper('helloworld');        -- HELLOWORLD

-- 14.将大写转化为小写
select lcase('HELLOWORLD');
select lower('HELLOWORLD');        -- helloworld

五:日期函数

MySQL的函数_第11张图片

MySQL的函数_第12张图片

MySQL的函数_第13张图片

MySQL的函数_第14张图片

MySQL的函数_第15张图片

MySQL的函数_第16张图片MySQL的函数_第17张图片MySQL的函数_第18张图片

MySQL的函数_第19张图片

MySQL的函数_第20张图片

MySQL的函数_第21张图片

-- 日期函数
 
-- 1.获取时间戳(毫秒值)
select unix_timestamp();

-- 2.将一个日期字符串转为毫秒值
select unix_timestamp('2021-12-21 08:08:08');-- 1640045288

-- 3.将时间戳毫秒值转为指定格式的日期
select from_unixtime(1640045288,'%Y-%m-%d %H:%i:%s');-- 2021-12-21 08:08:08

-- 4.获取当前的年月日
select curdate();
select current_date();                       -- 2024-01-29

-- 5.获取当前的时分秒
select current_time();
select curtime();                            -- 18:42:09

-- 6.获取年月日和时分秒
select current_timestamp();                  -- 2024-01-29 18:47:12

-- 7.从日期字符串中获取年月日
select date('2022-12-12 12:34:56');          -- 2022-12-12

-- 8.获取日期之间的差值
select datediff('2021-12-23','2008-08-08');  -- 4885

-- 9.获取时间之间的差值(秒级)
select timediff('12:12:34','10:18:56');      -- 01:53:38

-- 10.日期格式化
select date_format('2021-1-1 1:1:1','%Y-%m-%d %H:%i:%s');-- 2021-01-01 01:01:01

-- 11.将字符串转为日期
select str_to_date('August 10 2017','%M%d%Y');  -- 2017-08-10

-- 12.将日期进行减法(日期向前跳转)
select date_sub('2021-10-01',interval 2 day);   -- 2021-09-29
select date_sub('2021-10-01',interval 2 month); -- 2021-08-01

-- 13.将日期进行加法(日期向后跳转)
select date_add('2021-10-01',interval 2 day);   -- 2021-10-03
select date_add('2021-10-01',interval 2 month); -- 2021-12-01

-- 14.从日期中获取相关数据
select extract(hour from '2021-12-13 11:12:12'); -- 11
select extract(month from '2021-12-13 11:12:12');-- 12
select extract(year from '2021-12-13 11:12:12'); -- 2021

-- 15.获取给定日期所在月的最后一天
select last_day('2021-08-13');                 -- 2021-08-31

-- 16.获取指定年份和天数的日期
select makedate('2021',53);                    -- 2021年的第53天:2021-02-22

-- 17.从日期中获取相关数据
select year('2021-12-13 11:12:12');            -- 2021
select month('2021-12-13 11:12:12');           -- 12
select hour('2021-12-13 11:12:12');            -- 11
select quarter( '2021-12-13 11:12:12');        -- 获取季度:4

-- 18.根据日期获取信息
select monthname('2021-12-13 11:12:13');  -- 获取月份英文
select dayname('2021-12-13 11:12:13');    -- 获取周几英文
select dayofmonth('2021-12-13 11:12:13'); -- 当月的第几天
select dayofweek('2021-12-13 11:12:13');  -- 获取周几,1表示周日,2表示周一
select dayofyear('2021-12-13 11:12:13');  -- 获取一年的第几天
select week('2021-12-13 11:12:13');       -- 获取一年的第几周
select yearweek('2021-3-1');              -- 获取某年的第几周202109
select now();                             -- 获取当前时间

六:控制流函数

(1)if逻辑判断语句

MySQL的函数_第22张图片

-- IF
select if(5>3,'大于','小于'); -- 条件满足,返回第一个字段,不满足,返回第二个字段
select *,if(score>=85,'优秀','及格')flag from score;

-- IFNULL
select ifnull(5,0);          -- 第一个字段为null,则当作0处理,否则就返回其本身
select ifnull(null,0);
select *,ifnull(cumm,0) comm_flag from emp;

-- ISNULL
select isnull(5);            -- 不为null,返回0;为null,返回1
select isnull(null);

-- NULLIF
select nullif(12,12);        -- 相等返回null,不相等返回第一个字段
select nullif(12,13);

(2)case when 语句

MySQL的函数_第23张图片

use mydb1;
-- 创建订单表
create table orders(
 oid int primary key,  -- 订单id
 price double,				 -- 订单价格
 payType int           -- 支付方式
 );

insert into orders values(1,1200,1);
insert into orders values(2,1000,2);
insert into orders values(3,200,3);
insert into orders values(4,3000,1);
insert into orders values(5,1500,2);

-- 方式一
select
   *,
 case payType
    when 1 then '微信支付'
    when 2 then '支付宝支付'
	  when 3 then '银行卡支付'
    else 
       '其他支付方式'
	end as payTypeStr
	from orders;

-- 方式二
select
   *,
 case 
    when payType=1 then '微信支付'
    when payType=2 then '支付宝支付'
	  when payType=3 then '银行卡支付'
    else 
       '其他支付方式'
	end as payTypeStr
	from orders;

MySQL的函数_第24张图片MySQL的函数_第25张图片

七:窗口函数

1.介绍MySQL的函数_第26张图片

2.分类MySQL的函数_第27张图片

3.语法结构MySQL的函数_第28张图片

4.序号函数

MySQL的函数_第29张图片

MySQL的函数_第30张图片

MySQL的函数_第31张图片

MySQL的函数_第32张图片

 MySQL的函数_第33张图片

-- 求出每个部门薪资排在前三名的员工-分组求TOPN
select *
from
(
  select 
	 dname,
	 ename,
	 salary,
	 dense_rank() over(partition by dname order by salary desc) as rn
	 from employee
 ) t
 where t.rn<=3

 MySQL的函数_第34张图片

-- 对所有员工进行排序(不分组)
-- 不加partition表示全局排序
select
    dname,
	ename,
	salary,
	dense_rank() over(order by salary desc)as rn
from employee;

MySQL的函数_第35张图片

5.开窗聚合函数

(1)概念

在窗口中每条记录动态地应用聚合函数(   sun(),avg(),max(),min(),count()   ),可以动态计算在指定的窗口内的各种聚合函数值

(2)操作

select
    dname,
	ename,
	salary,
	sum(salary) over(partition by dname order by hiredate)as pv1
from employee;

MySQL的函数_第36张图片

select
    dname,
	ename,
	salary,
	sum(salary) over(partition by dname )as pv1
from employee;    -- 如果没有order by 排序语句 默认把分组内的所有数据进行sum操作

MySQL的函数_第37张图片

select
    dname,
	ename,
    hiredate,
	salary,
	sum(salary) over(partition by dname order by hiredate rows between unbounded preceding and current row)as c1
from employee;-- 从开头行加到现在行

MySQL的函数_第38张图片

select
    dname,
	ename,
	salary,
	sum(salary) over(partition by dname order by hiredate rows between 3 preceding and current row)as c1
from employee;-- 现在行的前三行加上现在行

MySQL的函数_第39张图片

select
    dname,
	ename,
	salary,
	sum(salary) over(partition by dname order by hiredate rows between 3 preceding and 1 following)as c1
from employee;-- 现在行的前三行加上现在行加上现在行的后一行

MySQL的函数_第40张图片

select
    dname,
	ename,
	salary,
	sum(salary) over(partition by dname order by hiredate rows between current row  and undounded following)as c1
from employee;-- 从当前行加到最后

MySQL的函数_第41张图片

6.分布函数

(1)cume_dist()

用途:分组内小于,等于当前rank值的行数/分组内总行数

应用场景:查询小于等于当前薪资(salary)的比例

select
    dname,
	ename,
	salary,
	cume_dist() over( order by salary)as c1,
	cume_dist()  over(partition by dname order by salary)as c2
from employee;

 /*c1:(不加partition by,不分组)
      第一个:salary少于等于3000的有3个人,总共12个人
						3/12=0.25
	 c2:(加partition by,分组)
    研发部第一个:salary少于等于3000的有1个人,总共6个人
						1/6=0.16666666667
 */

MySQL的函数_第42张图片

(2)percent_rank()

用途:每行按照公式(rank-1)/(rows-1)进行计算,其中,rank为rank()函数产生的序号,rows为当前窗口的记录总数

select
    dname,
	ename,
	salary,
	rank() over(partition by dname order by salary desc)as rn,
	percent_rank() over(partition by dname order by salary)as rn2
from employee;

/*
  rn2:
    第一行:(1-1)/(6-1)= 0  
    第二行:(1-1)/(6-1)= 0  
    第三行:(2-1)/(6-1)= 0.4
*/

MySQL的函数_第43张图片

7.前后函数(lag和lead)

用途:返回位于当前行的前n行(lag(expr,n))或后n行(lead(expr,n))的expr的值

应用场景:查询前1名同学的成绩和当前同学成绩的差值

select
    dname,
	ename,
	salary,
	hiredate,
	lag(hiredate,1,'2000-01-01') over(partition by dname order by hiredate )as time1,
            -- 返回上一行的内容,没有值时默认为2000-01-01
	lag(hiredate,2) over(partition by dname order by hiredate)as time2           
            -- 返回上两行的内容,没有值时为null
from employee;

MySQL的函数_第44张图片

select
  dname,
	ename,
	salary,
	hiredate,
	lead(hiredate,1,'2000-01-01') over(partition by dname order by hiredate )as time1,
          -- 返回下一行的内容,没有值时默认为2000-01-01
	lead(hiredate,2) over(partition by dname order by hiredate)as time2
          -- 返回下两行的内容,没有值时为null
from employee;

MySQL的函数_第45张图片

8.头尾函数(first_value和last_value)

用途:返回第一个(first_value)或最后一个(last_value)expr的值

应用场景:截至到当前,按照日期排序查询第1个入职和最后1个入职员工的薪资

select
    dname,
	ename,
	salary,
	hiredate,
	first_value(salary) over(partition by dname order by hiredate )as first,
	last_value(salary) over(partition by dname order by hiredate)as last
from employee;

MySQL的函数_第46张图片

9.其他函数

(1)nth_value(expr,n) 

用途:返回窗口中第n个expr的值,expr可以是表达式,也可以是列名

应用场景:截至到当前薪资,显示每个员工的薪资中排名第2或者第3的薪资

select
    dname,
	ename,
	salary,
	hiredate,
	nth_value(salary,2) over(partition by dname order by hiredate )as second_salary,
               -- 从当前行开始,排名的2的薪资
	nth_value(salary,3) over(partition by dname order by hiredate)as third_salary
               -- 从当前行开始,排名的3的薪资
from employee;

MySQL的函数_第47张图片

(2)ntile(n)   

用途:将分区中的有序数据分为n个等级,记录等级数

应用场景:将每个部门员工按照入职日期分为3组

select
    dname,
	ename,
	salary,
	hiredate,
	ntile(3) over(partition by dname order by hiredate)as nt
from employee;

MySQL的函数_第48张图片

-- 取出每个部门的第一组员工
select
*
from(
    select
    dname,
	ename,
	salary,
	hiredate,
	ntile(3) over(partition by dname order by hiredate)as nt
from employee
)t
where t.nt = 1;

MySQL的函数_第49张图片

你可能感兴趣的:(mysql,数据库)