【MySQL数据库基本操作06--函数】

MySQL的函数

1. 聚合函数

count\sum\min\max\avg

重点:group_concat()

-- 将所有员工的名字合并成一行 
select group_concat(emp_name) from emp;
-- 指定分隔符合并 
select group_concat(emp_name separator ';') from emp;
-- 指定排序方式和分隔符 
select department,group_concat(emp_name separator ';') from emp group by department;
select department,group_concat(emp_name order by salary separator ';') from emp group by department;

2. 数学函数

【MySQL数据库基本操作06--函数】_第1张图片
【MySQL数据库基本操作06--函数】_第2张图片
【MySQL数据库基本操作06--函数】_第3张图片

select ceil(1.1);--2
select floor(1.1); --1
select greatest(1,2,3);--3   # max返回字段的最大值,greatest返回列表的最大值
select least(1,2,3); --1
select mod(5/2);  --1
select pow(3,2);  --9
select floor(rand() * 100);
select round(3.568); --4
select round(3.568,2); --3.57
select truncate(3.568,2); --3.56

3. 字符串函数

#1 获取字符串字符个数
select char_length('hello');-- 5 length返回字节数
#2 concat字符串合并
select concat('hello','world'); -- helloworld
#3 指定分隔符进行合并
select concat_ws('-','hello','world'); -- hello-world
#4 返回第一个字符串 s 在字符串列表(s1,s2...)中第一次出现的位置
select field('a','a','b','c'); -- 1
#5 去除左边\右边\两端空格
select ltrim('   abc'),rtrim('abc   '),trim('  abc   ');
#6 从字符串 s 的 n 位置截取长度为 len 的子字符串,同 SUBSTRING(s,n,len)
select mid('helloworld',2,3); # ell
# 从字符串 s 中获取 s1 的开始位置,POSITION(s1 IN s)
select position('a' in 'nation'); #2
# 替换
select replace('abc','a','x'); # xbc
# 翻转
select reverse('abc'); #'cba'
# 返回字符串后n个字符
select right('hello',2); # lo
# 字符串比较
select strcmp('hello','world');  #-1,w>h
# 字符串截取
select substr('hello',2,3) #'ell'
# upper/lower 转换大小写
select upper('hello'); 'HELLO'

4. 日期函数

select unix_timestamp();
select unix_timestamp(2021-12-25 16:32:06);
# 将毫秒值时间戳转为指定格式日期
SELECT FROM_UNIXTIME(1598079966,'%Y-%m-%d %H:%i:%s'); 
# 获取当前年月日
select curdate();
# 获取当年时分秒
select curtime();
# 获取当前日期和时间
SELECT CURRENT_TIMESTAMP();
# 从日期或日期时间表达式中提取日期值
SELECT DATE(current_timestamp());    
# 计算日期 d1->d2 之间相隔的天数
SELECT DATEDIFF('2001-01-01','2001-02-02')
# 计算时间差值(秒级)
SELECT TIMEDIFF("13:10:11", "13:10:10");
# 日期格式化
select date_format('2021-1-1 1:1:1','%Y-%m-%d %H:%i:%s');
# 字符串转为日期
select str_to_date('2017-10-10','%Y-%m-%d');
# 将日期进行减法(date_sub)、加法(date_add);type值也可以多种
select date_sub('2021-10-01',interval 2 day);
# 从日期中获取小时
select extract(hour from '2021-12-25 20:01:10');
# 返回给给定日期的那一月份的最后一天
select last_day('2021-12-25');
# 获取指定年和天数的日期
select makedate('2021',100);
# 返回第几季节
select quarter('2021-5-20');

5. 控制流函数

5.1 if

# if(expr,v1,v2)
SELECT IF(1 > 0,'正确','错误'); 
# ifnull 如果 v1 的值不为 NULL,则返回 v1,否则返回 v2。
SELECT IFNULL(null,'Hello Word')
# isnull 判断表达式是否为 NULL
SELECT ISNULL(NULL);
# nullif 比较两个字符串,如果字符串 expr1 与 expr2 相等 返回 NULL,否则返回 expr1
select nullif()

5.2 case when

'''CASE expression
    WHEN condition1 THEN result1
    WHEN condition2 THEN result2
   ...
    WHEN conditionN THEN resultN
    ELSE result
END'''

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

6. 窗口函数

MySQL 8.0 新增窗口函数,窗口函数又被称为开窗函数

【MySQL数据库基本操作06--函数】_第4张图片

window_function ( expr ) OVER ( 
  PARTITION BY ... 
  ORDER BY ... 
  frame_clause 
)
'''
其中window_function 是窗口函数的名称;expr 是参数,有些函数不需要参数;OVER子句包含三个选项:
分区(PARTITION BY)
PARTITION BY选项用于将数据行拆分成多个分区(组),它的作用类似于GROUP BY分组。如果省略了 PARTITION BY,所有的数据作为一个组进行计算
排序(ORDER BY)
OVER 子句中的ORDER BY选项用于指定分区内的排序方式,与 ORDER BY 子句的作用类似
以及窗口大小(frame_clause)。
frame_clause选项用于在当前分区内指定一个计算窗口,也就是一个与当前行相关的数据子集。 
'''

6.1 序号函数

序号函数有三个:

ROW_NUMBER()、RANK()、DENSE_RANK(),可以用来实现分组排序,并添加序号。

不加partition by表示全局排序

row_number()|rank()|dense_rank() over ( 
  partition by ... 
  order by ... 
) 

SELECT
	dname,
	ename,
	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;

【MySQL数据库基本操作06--函数】_第5张图片

6.2 开窗聚合函数

select  
 dname,hiredate,
 ename,
 salary,
 sum(salary) over(partition by dname order by hiredate  rows between unbounded preceding and current row),
 sum(salary) over(partition by dname) as pv3
from employee;  -- 如果没有order  by排序语句  默认把分组内的所有数据进行sum操作

【MySQL数据库基本操作06--函数】_第6张图片

6.3 分布函数

CUME_DIST:

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

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

SELECT
	dname,
	ename,
	salary,
	round( cume_dist() over ( ORDER BY salary ), 2 ) AS rn1,-- 没有partition语句 所有的数据位于一组
	round( cume_dist() over ( PARTITION BY dname ORDER BY salary ), 2 ) AS rn2 
FROM
	employee;

PERCENT_RANK:

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

•应用场景:不常用

7. 前后函数

•用途:返回位于当前行的前n行(LAG(expr,n))或后n行(LEAD(expr,n))的expr的值

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

SELECT
	dname,
	ename,
	hiredate,
	salary,
	lag( hiredate, 1, '2000-01-01' ) over ( PARTITION BY dname ORDER BY hiredate ) AS last_1_time,
	lag( hiredate, 2 ) over ( PARTITION BY dname ORDER BY hiredate ) AS last_2_time 
FROM
	employee;
/*
last_1_time: 指定了往上第1行的值,default为'2000-01-01'  
                         第一行,往上1行为null,因此取默认值 '2000-01-01'
                         第二行,往上1行值为第一行值,2021-11-01 
                         第三行,往上1行值为第二行值,2021-11-02 
last_2_time: 指定了往上第2行的值,为指定默认值
                         第一行,往上2行为null
                         第二行,往上2行为null
                         第四行,往上2行为第二行值,2021-11-01 
                         第七行,往上2行为第五行值,2021-11-02 
*/
-- lead的用法
select 
 dname,
 ename,
 hiredate,
 salary,
 lead(hiredate,1,'2000-01-01') over(partition by dname order by hiredate) as last_1_time,
 lead(hiredate,2) over(partition by dname order by hiredate) as last_2_time 
from employee;

8. 头尾函数

•用途:返回第一个(FIRST_VALUE(expr))或最后一个(LAST_VALUE(expr))expr的值

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

-- 注意,  如果不指定ORDER BY,则进行排序混乱,会出现错误的结果
select
  dname,
  ename,
  hiredate,
  salary,
  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数据库基本操作06--函数】_第7张图片

9. 其他函数

​ NTH_VALUE(expr,n)

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

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

-- 查询每个部门截止目前薪资排在第二和第三的员工信息
select 
  dname,
  ename,
  hiredate,
  salary,
  nth_value(salary,2) over(partition by dname order by hiredate) as second_score,
  nth_value(salary,3) over(partition by dname order by hiredate) as third_score
from employee

【MySQL数据库基本操作06--函数】_第8张图片

NTILE(n)

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

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

-- 根据入职日期将每个部门的员工分成3组
select 
  dname,
  ename,
  hiredate,
  salary,
ntile(3) over(partition by dname order by  hiredate  ) as rn 
from employee;

【MySQL数据库基本操作06--函数】_第9张图片

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