MySQL函数

函数

一.聚合函数

(1)概述

group_concat(),该函数用于实现行的合并,group——concat()函数首先根据 group by 指定的列进行分组,并且用分隔符分割,将同一个分组中的值连接起来,返回一个字符串结果。

(2)格式

屏幕截图 2023-12-18 151748.png
说明:

  • 使用 distinct 可以排除重复值;
  • 如果需要对结果中的值进行排序,可以使用 order by 子句;
  • separator 是一个字符串值,默认为逗号。

屏幕截图 2023-12-18 152247.png

二.数学函数

屏幕截图 2023-12-18 153622.png

屏幕截图 2023-12-18 153639.png
屏幕截图 2023-12-18 153717.png
代码实现:

-- 取绝对值
select abs(-10); -- 10
select abs(10); -- 10

-- 向上取整
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-1的随机数
select floor(rand()*100);

-- 取小数的四舍五入
select round(3.3415);
select round(3.3415,3); -- 保留3位小数

-- 将小数直接截取到指定位数
select truncate(3.1415,3); -- 3.141

三.字符串函数

屏幕截图 2023-12-18 154130.png

屏幕截图 2023-12-18 154801.png

屏幕截图 2023-12-18 160411.png
屏幕截图 2023-12-18 161522.png

-- 1.获取字符串字符个数
select char_length('hello'); -- 5
select char_length('你好吗'); -- 3

-- length取长度,返回的单位是字节
select length('hello'); -- 5
select length('你好吗'); -- 9

-- 2.将多个字符串进行合并
select concat('hello','world'); -- helloworld

-- 使用分隔符将多个字符串合并
select concat_ws(';','hello','World','MySQL');

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

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

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

-- 6.获取字符串A在字符串中出现的位置
select position('abc' in 'habcelloabcworld');

-- 7字符串替换
select replace('aaahelloworldaaa','aaa','bbb');

-- 8.字符串反转
select reverse('hello');

-- 9。返回字符串s的后n个字符
select right('hello',3);

-- 10.比较字符串s1和s1,
-- 如果s1与s2相等返回0,如果s1>s2返回1,如果s1<s2返回-1
select strcmp('hello','world');

-- 11.字符串截取
select substr('hello',2,3); -- 从第二个字符开始截取,截取3个字符
select substring('hello',2,3); -- 从第二个字符开始截取,截取3个字符

-- 12.将大写转小写
select ucase('helloWorld');
select upper('helloWorld');

-- 13.将大写转为小写
select lcase('HELLOWORLD');
select lower('APP');

四.日期函数

屏幕截图 2023-12-18 163343.png
屏幕截图 2023-12-18 163355.png
屏幕截图 2023-12-18 163552.png
屏幕截图 2023-12-18 165610.png
屏幕截图 2023-12-18 165636.png
屏幕截图 2023-12-18 165654.png
屏幕截图 2023-12-18 165715.png

-- 1.返回从1970-01-01 00:00:00到当前毫秒值
select unix_timestamp();

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

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

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

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

-- 6.获取年月日 和 时分秒
select current_timestamp();

-- 7.从日期字符串中获取年月日
select date('2023-12-18 16:31:09');

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

-- 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');

-- 11将字符串转为日期
select str_to_date('2021-12-13 11:11:11','%Y-%m-%d %H-%i-%s');

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

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

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

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

-- 17.根据日期获取年月日,时分秒
select year( '2021-12-13 11:12:13');
select month( '2021-12-13 11:12:13');
select day( '2021-12-13 11:12:13');
select quarter( '2021-12-13 11:12:13'); -- 获取季度


-- 18.根据日期获取信息
select monthname('2021-12-13 11:12:13'); -- 获取月份的英文
select dayname('2021-12-13 11:12:13'); -- 获取周几:Monday
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'); -- 获取一年的第几天

五.控制流函数

if 逻辑判断语句

屏幕截图 2023-12-18 170524.png

-- if
select if(1>0,'true','false');

-- ifnull
select ifnull(5,0);
select ifnull(null,0);

-- isnull
select isnull(5);
select isnull(null);

-- nullif
select nullif(12,12); -- null
select nullif(12,13); -- 12

case-when 语句

屏幕截图 2023-12-18 170650.png
代码应用实现

create table orders(
    oid int primary key , -- 订单id
    price double, -- 订单价格
    payType int -- 支付方式(1:微信支付 2:支付宝支付 3:银行卡支付 4:其他)
);

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,3);
insert into orders values (5,1500,1);

select
    *,
    case payType
        when 1 then '微信支付'
        when 2 then '支付宝支付'
        when 3 then '银行支付'
        when 4 then '其他'
    else 'sorry'
end as payTypeStr
from orders;

执行结果:
屏幕截图 2023-12-18 172000.png

六.窗口函数

(1)介绍

  • MySQl8.0 新增窗口函数,窗口函数又被称为开窗函数,与 Oracle 窗口函数类似,属于 MySQl 的一大特点
  • 非聚合窗口函数是相对于聚函数来说的。聚合函数是对一组数据计算后返回单个值(即分组),非聚合函数一次只会处理一行数据。窗口聚合函数在行记录上计算某个字段的结果时,可将窗口范围内的数据输入到聚合函数中,并不改变行数。

屏幕截图 2023-12-18 172540.png
屏幕截图 2023-12-18 181759.png

(2)序号函数

屏幕截图 2023-12-19 192707.png
partition by 表示分组,order by 表示按照什么方式排序
例子:对每个部门的员工按照薪资排序,并输出排名

select
    dname,
    ename,
    eid,
    salary,
    row_number() over (partition by dname order by salary desc) as rn1,
    rank() over (partition by dname order by salary desc) as rn2,
    dense_rank() over (partition by dname order by salary desc) as rn3
from employee;

执行结果:
屏幕截图 2023-12-19 195346.png

(3)开窗聚合函数

屏幕截图 2023-12-19 200036.png
此以 sum 为例,

1).从开头加到当前行

两种方法:

select
    dname,
    ename,
    salary,
    sum(salary) over(partition by dname order by hiredate) as pv1
from employee;  
select
    dname,
    ename,
    hiredate,
    salary,
    sum(salary) over(partition by dname order by hiredate rows between unbounded preceding and current row ) as pv1
from employee;

执行结果:
屏幕截图 2023-12-19 201517.png

2).没有 order by,默认把分组后的所有相加
select
    dname,
    ename,
    hiredate,
    salary,
    sum(salary) over(partition by dname ) as pv2
from employee;

执行结果:
屏幕截图 2023-12-19 201715.png

3).从前三行加到当前行
select
    dname,
    ename,
    hiredate,
    salary,
    sum(salary) over(partition by dname order by hiredate rows between 3 preceding and current row ) as pv1
from employee;

执行结果:
屏幕截图 2023-12-19 201920.png

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

屏幕截图 2023-12-19 202018.png

(4).分布函数——cume_dist 和 percent_rank

cume_dist
  • 用途:分组内小于,等于当前 rank 值的行数/分组内总行数
  • 应用场景:查询小于等于当前薪资的比例
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;

执行结果:
屏幕截图 2023-12-19 203608.png
解释:(rn1 = c1,rn2 = c2)
屏幕截图 2023-12-19 203627.png

percent_rank

(不常用)

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

屏幕截图 2023-12-19 203943.png

(5).前后函数 lag 和 lead

  • 用途:返回位于当前行的前 n 行(lag(expr,n))或后 n 行(lead(expr,n)的 expr 的值。
  • 应用场景:查询前 1 名同学 的成绩和当前同学成绩从差值
select
    dname,
    ename,
    salary,
    hiredate,
    lag(hiredate,1,'2020-11-01') over (partition by dname order by hiredate) as c1,
    lead(hiredate,2) over (partition by dname order by hiredate) as c2
from employee;

执行结果:
屏幕截图 2023-12-19 205037.png
c1:表示的是前一个的时间,如果是第一个,则是自身所填的默认值
c2:表示的是后两个的时间,没有写默认值,所有在没有时,为 null

(6)头尾函数 first_value 和 last_value

  • 用途:返回第一个(first_value(expr))或最后一个(last_value(expr))expr 的值
  • 应用场景:截止到当前,按照日期排序查询第 1 个入职和最后 1 个入职员工的薪资

屏幕截图 2023-12-19 205623.png

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;

执行结果:
屏幕截图 2023-12-19 205943.png

(7)其他函数 nth_value,ntile

nth_value
  • 用途:返回窗口中第 n 个 expr 的值,expr 可以是表达式,也可以是列名
  • 应用场景:截止到当前薪资,显示每个员工的薪资中排名第二或第三的薪资

屏幕截图 2023-12-19 210708.png
执行结果:
屏幕截图 2023-12-19 210749.png

ntile
  • 用途:将分区中的有序数据分为 n 个等级,记录等级数
  • 应用场景:将每个部门员工按照入职日期分成 3 组

屏幕截图 2023-12-19 211300.png

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值