MySQL---控制流函数、窗口函数(序号函数、开窗聚合函数、分布函数、前后函数、头尾函数、其他函数)

这篇具有很好参考价值的文章主要介绍了MySQL---控制流函数、窗口函数(序号函数、开窗聚合函数、分布函数、前后函数、头尾函数、其他函数)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. 控制流函数

格式

解释

案例

IF(expr,v1,v2)

如果表达式 expr 成立,返回结果 v1;否则,返回结果 v2

SELECT IF(1 > 0,'正确','错误')   

->正确

IFNULL(v1,v2)

如果 v1 的值不为 NULL,则返回 v1,否则返回 v2

SELECT IFNULL(null,'Hello Word')

->Hello Word

ISNULL(expression)

判断表达式是否为 NULL

SELECT ISNULL(NULL);

->1

NULLIF(expr1, expr2)

比较两个字符串,如果字符串 expr1 expr2 相等 返回 NULL,否则返回 expr1

SELECT NULLIF(25, 25);

->

格式

解释

操作

CASE expression

    WHEN condition1 THEN result1

    WHEN condition2 THEN result2

   ...

    WHEN conditionN THEN resultN

    ELSE result

END

CASE 表示函数开始,END 表示函数结束。如果 condition1 成立,则返回 result1, 如果 condition2 成立,则返回 result2,当全部不成立则返回 result,而当有一个成立之后,后面的就不执行了。

select case 100 when 50 then 'tom'

when 100 then 'mary'else 'tim' end ;

select case when 1=2 then 'tom'

when 2=2 then 'mary' else'tim' end ;

use mydb4; 
-- 创建订单表
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,1);
insert into orders values(5,1500,2);

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

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

2. 窗口函数

非聚合窗口函数是相对于聚合函数来说的。聚合函数是对一组数据计算后返回单个值(即分组),非聚合函数一次只会处理一行数据。窗口聚合函数在行记录上计算某个字段的结果时,可将窗口范围内的数据输入到聚合函数中,并不改变行数

MySQL---控制流函数、窗口函数(序号函数、开窗聚合函数、分布函数、前后函数、头尾函数、其他函数)

MySQL---控制流函数、窗口函数(序号函数、开窗聚合函数、分布函数、前后函数、头尾函数、其他函数)

-- 语法:
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选项用于在当前分区内指定一个计算窗口,也就是一个与当前行相关的数据子集。

数据准备:

use mydb4; 
create table employee( 
   dname varchar(20), -- 部门名 
   eid varchar(20), 
   ename varchar(20), 
   hiredate date, -- 入职日期 
   salary double -- 薪资
); 
insert into employee values('研发部','1001','刘备','2021-11-01',3000);
insert into employee values('研发部','1002','关羽','2021-11-02',5000);
insert into employee values('研发部','1003','张飞','2021-11-03',7000);
insert into employee values('研发部','1004','赵云','2021-11-04',7000);
insert into employee values('研发部','1005','马超','2021-11-05',4000);
insert into employee values('研发部','1006','黄忠','2021-11-06',4000);
 
insert into employee values('销售部','1007','曹操','2021-11-01',2000);
insert into employee values('销售部','1008','许褚','2021-11-02',3000);
insert into employee values('销售部','1009','典韦','2021-11-03',5000);
insert into employee values('销售部','1010','张辽','2021-11-04',6000);
insert into employee values('销售部','1011','徐晃','2021-11-05',9000);
insert into employee values('销售部','1012','曹洪','2021-11-06',6000);

 2.1 序号函数

序号函数有三个:ROW_NUMBER()RANK()DENSE_RANK(),可以用来实现分组排序,并添

加序号。

-- 语法:
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 rn 
from employee;
-- 对每个部门的员工按照薪资排序,并给出排名 rank
select 
dname,
ename,
salary,
rank() over(partition by dname order by salary desc) as rn 
from employee;
-- 对每个部门的员工按照薪资排序,并给出排名 dense-rank
select 
dname,
ename,
salary,
dense_rank() over(partition by dname order by salary desc) as rn 
from employee;
--求出每个部门薪资排在前三名的员工- 分组求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
-- 对所有员工进行全局排序(不分组)
-- 不加partition by表示全局排序
select 
     dname,
     ename,
     salary,
     dense_rank() over( order by salary desc)  as rn
from employee;

2.2 开窗聚合函数

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

2.3 分布函数

CUME_DIST:

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

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

select  
 dname,
 ename,
 salary,
 cume_dist() over(order by salary) as rn1, -- 没有partition语句 所有的数据位于一组
 cume_dist() over(partition by dept order by salary) as rn2 
from employee;

/*
rn1: 没有partition,所有数据均为1组,总行数为12,
     第一行:小于等于3000的行数为3,因此,3/12=0.25
     第二行:小于等于4000的行数为5,因此,5/12=0.4166666666666667
rn2: 按照部门分组,dname='研发部'的行数为6,
     第一行:研发部小于等于3000的行数为1,因此,1/6=0.16666666666666666
*/

PERCENT_RANK :

每行按照公式(rank-1) / (rows-1)进行计算。其中,rankRANK()函数产生的序号,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 desc ) as rn2
from employee;

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

2.4 前后函数

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

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

-- lag的用法
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;

2.5 头尾函数

返回第一个(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;

2.6 其他函数

NTH_VALUE(expr,n):

返回窗口中第nexpr的值。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

NTILE: 

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

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

-- 根据入职日期将每个部门的员工分成3组
select 
  dname,
  ename,
  hiredate,
  salary,
ntile(3) over(partition by dname order by  hiredate  ) as rn 
from employee;
-- 取出每个部门的第一组员工
select
*
from
(
    SELECT 
        dname,
        ename,
        hiredate,
        salary,
    NTILE(3) OVER(PARTITION BY dname ORDER BY  hiredate  ) AS rn 
    FROM employee
)t
where t.rn = 1;

 文章来源地址https://www.toymoban.com/news/detail-443457.html

(日常美图时间)

MySQL---控制流函数、窗口函数(序号函数、开窗聚合函数、分布函数、前后函数、头尾函数、其他函数)

 

到了这里,关于MySQL---控制流函数、窗口函数(序号函数、开窗聚合函数、分布函数、前后函数、头尾函数、其他函数)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【大数据之Hive】十六、Hive-HQL函数之窗口函数(开窗函数)

      先定义了窗口的大小(按行来算),然后对窗口内的行的数据进行计算,再将计算结果返回给改行。   窗口函数包括窗口和函数两部分,窗口用于定义计算范围,函数用于定义计算逻辑,窗口函数只会在原来的表上增加一列结果列,不改变原来的数据。 函数:   绝

    2024年02月11日
    浏览(39)
  • MySQL 时间日期函数,流程控制函数,加密解密函数以及聚合查询函数

    注:本文仅作为查找函数和部分理解使用,希望能给大家带来帮助 以下函数均可以使用 重点记忆前三个红色标注的函数, 第一个函数返回值如2024-01-02的形式 第二个如 15:20:21 第三个则是两者追加 如: 2024-01-02 15:20:21 注:注意 DAYOFWEEK 和 WEEKDAY 的区别   相当于取date的某个单独的字

    2024年01月23日
    浏览(50)
  • 开窗函数的使用详解(窗口范围ROWS与RANGE图文详解)

    函数名(参数) OVER (PARTITION BY子句 ORDER BY子句 ROWS/RANGE子句) 由三部分组成: 函数名:如sum、max、min、count、avg等聚合函数以及lead、lag行比较函数等; over: ,表示前面的函数是分析函数,不是普通的集合函数; 分组子句:over后面挂号内的内容; 分析子句又由下

    2024年02月04日
    浏览(73)
  • 窗口函数OVER(PARTITION BY)详细用法——语法+函数+开窗范围ROWS和RANGE

    目录 一、函数写法 二、开窗的窗口范围ROWS与RANGE 1.范围限定用法 2.ROWS和RANGE的区别 (1) ROWS按行数限定 (2) RANGE按数据范围限定         order by 数字                 例1    汇总数据范围为:[当前行值,当前行值+3]                 例2    汇总数据范围为:

    2023年04月08日
    浏览(53)
  • mysql 8.0 窗口函数 之 分布函数 与 sql server (2017以后支持) 分布函数 一样

    mysql 分布函数 percent_rank() :等级值 百分比 cume_dist() :累积分布值 percent_rank() 计算方式 (rank-1)/(rows-1), 其中 rank 的值为使用RANK()函数产生的序号,rows 的值为当前窗口的总记录数。

    2024年02月11日
    浏览(42)
  • MySQL:开窗函数

    当查询条件需要用到复杂子查询时,聚合函数操作起来非常麻烦,因此使用开窗函数能够轻松实现。 注意:在Oracle中称为分析函数。            在MySQL中称为开窗函数,使用于MySQL8.0以上版本,sql sever、hive、Oracle等。 开窗函数:为将要被操作的行的集合定义一个窗口,它对

    2023年04月18日
    浏览(28)
  • 聚合函数与窗口函数

    聚合函数(Aggregate Functions)是SQL中的函数,用于对一组数据进行计算,并返回单个结果。聚合函数通常用于统计和汇总数据,包括计算总和、平均值、计数、最大值和最小值等。 以下是一些常见的聚合函数: SUM():计算指定列或表达式的总和。 AVG():计算指定列或表达式的

    2024年02月10日
    浏览(44)
  • 【Mysql系列】LAG与LEAD开窗函数

    💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学习,不断总结,共同进步,活到老学到老 导航 檀越剑指大厂系列:全面总

    2024年02月05日
    浏览(47)
  • MySQL8.0数据库开窗函数

          数据库开窗函数是一种在SQL中使用的函数,它可以用来对结果集中的数据进行分组和排序,以便更好地分析和处理数据。开窗函数与聚合函数不同,它不会将多行数据聚合成一行,而是保留每一行数据,并对其进行分组和排序。 常见的开窗函数包括ROW_NUMBER()、RANK()、

    2024年02月08日
    浏览(63)
  • Hive学习---4、函数(单行函数、高级聚合函数、炸裂函数、窗口函数)

    1.1 函数简介 Hive会将常用的逻辑封装成函数给用户进行使用,类似java中的函数。 好处:避免用户反复写逻辑,可以直接拿来使用 重点:用户需要知道函数叫什么,能做什么 Hive提供了大量的内置函数,按照其特点大致可分为如下几类:单行函数、聚合函数、炸裂函数、窗口

    2024年02月08日
    浏览(59)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包