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

news2025/1/31 3:16:10

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. 窗口函数

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

-- 语法:
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;

 

(日常美图时间)

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/521251.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JVM垃圾收集器(一)

目录 1、如何考虑 GC 2、如何确定一个对象“死去” 3、分代收集理论 4、垃圾回收算法 5、HotSpot的算法实现细节 1、如何考虑 GC 垃圾收集&#xff08;Garbage Collection&#xff0c;GC&#xff09;的历史比Java更久远&#xff0c;1960年诞生于MIT。 GC 需要考虑的三件事…

UNIAPP实战项目笔记72 提交订单到选择支付方式的前后端交互

UNIAPP实战项目笔记72 提交订单到选择支付方式的前后端交互 思路 购物车确认订单,跳转到订单确认界面确认支付后清除购物车对应id的数据 实例截图 清空购物车数据后 代码 前端代码 order.js export default{state:{// 订单号orderNumber:},getters:{},mutations:{initOr…

数字化转型浪潮下,如何选择适合企业的低代码平台

近日&#xff0c;艾瑞咨询发布了《数字新生态&#xff1a;中国低代码厂商发展白皮书》&#xff08;以下简称“报告”&#xff09;&#xff0c;在该报告中&#xff0c;艾瑞咨询对中国当前的低代码市场进行了非常细致的解构&#xff0c;并针对当前企业数字化转型&#xff0c;对低…

电阻传感器工作原理

金属随着温度变化&#xff0c;其电阻值也发生变化。 对于不同金属来说&#xff0c;温度每变化一度&#xff0c;电阻值变化是不同的&#xff0c;而电阻值又可以直接作为输出信号。 电阻共有两种变化类型 正温度系数 温度升高 阻值增加 温度降低 阻值减少 负温度系数 温…

【一起啃书】《机器学习》第七章 贝叶斯分类器

文章目录 第七章 贝叶斯分类器7.1 贝叶斯决策论7.2 极大似然估计7.3 朴素贝叶斯分类器7.4 半朴素贝叶斯分类器7.5 贝叶斯网7.6 EM算法 第七章 贝叶斯分类器 7.1 贝叶斯决策论 对分类任务来说&#xff0c;在所有相关概率都已知的理想情形下&#xff0c;贝叶斯决策论考虑如何基于…

k8s学习-CKS真题-利用AppArmor进行应用行为限制

目录 题目环境搭建解题模拟题参考 题目 Task 在 cluster 的工作节点 node02 上&#xff0c;实施位于 /etc/apparmor.d/nginx_apparmor 的现有 APPArmor 配置文件。 编辑位于 /cks/KSSH00401/nginx-deploy.yaml 的现有清单文件以应用 AppArmor 配置文件。 最后&#xff0c;应用清…

UE4及Airsim安装时遇到的问题及解决办法

UE4及Airsim安装时遇到的问题及解决办法 目录 UE4及Airsim安装时遇到的问题及解决办法前言UE4下载慢解决方法 Airsim编译过程中提示&#xff1a;无法打开包括文件: “Eigen/Dense”: No such file or directory [D:\software\Visual_studio2022\2022Community\AirSim\Air解决办…

C语言——运算符和表达式

所谓表达式就是指由运算符、运算量和标点符号组成的有效序列&#xff0c;其目的是说明一个计算过程。表达式可以独立成语句&#xff1a;表达式; 运算符按功能分为&#xff1a;算术运算、赋值运算、关系运算、逻辑运算、位运算以及其他运算符 1. 算术运算符&#xff1a; - * / %…

项目部署 | Linux安装Git和Maven

知识目录 一、写在前面✨二、安装Git&#x1f495;2.1 yum安装git2.2 新建Git仓库2.3 拉取仓库代码 三、安装Maven&#x1f495;3.1 上传Maven压缩包并解压3.2 配置环境变量3.3 设置本地仓库3.4 设置中央仓库 四、总结撒花&#x1f60a; 一、写在前面✨ 大家好&#xff01;我是…

二叉树的递归遍历与迭代遍历(图示)

文章目录 前言1. 二叉树的递归遍历&#xff08;一入递归深似海&#xff0c;从此offer是路人&#xff09;1.1 [前序遍历](https://leetcode.cn/problems/binary-tree-preorder-traversal/)1.2 [中序遍历](https://leetcode.cn/problems/binary-tree-inorder-traversal/)1.3 [后序…

实验一 Python基础编程

实验一 Python基础编程 只为给原因学习编程的同学提供一个思路&#xff0c;让编程更简单&#xff01;&#xff01;&#xff01; 本博主擅长整理粉丝的私信&#xff01;只要你有需求就可以告诉博主&#xff01;博主可以帮你解决并发表&#xff01; 一、实验学时 2学时 二、实…

docker发布到dockerhub报错denied: requested access to the resource is denied

docker发布到dockerhub报错denied: requested access to the resource is denied 解决方案 修改发布的镜像的REPOSITORY为自己的账户名镜像&#xff0c;比如我的用户名是luobotoutou123。docker tag tomcat02:1.0 luobotoutou123/tomcat02:1 然后发布镜像 到dockerhub远程仓库…

学习杂记 2023.5.13 单词背诵

目录 鼠标上的DPI是什么&#xff1f; 鼠标上的DPI是什么&#xff1f; DPI是英文Dots Per Inch的缩写&#xff0c;意思是每英寸点数。在计算机中&#xff0c;DPI通常用于描述指针设备&#xff08;例如鼠标&#xff09;的精度。在鼠标上&#xff0c;DPI指的是鼠标移动时指针在屏…

[图神经网络]ViG(Vision GNN)网络代码实现

论文解读&#xff1a; [图神经网络]视觉图神经网络ViG(Vision GNN)--论文阅读https://blog.csdn.net/weixin_37878740/article/details/130124772?spm1001.2014.3001.5501代码地址&#xff1a; ViGhttps://github.com/huawei-noah/Efficient-AI-Backbones/tree/master/vig_p…

Hive之DDL

目录 对数据库操作&#xff1a; 创建数据库&#xff1a; 查看数据库信息&#xff1a; 1.查看基本信息&#xff1a; 2.查看详尽信息&#xff1a; 删除数据库&#xff1a; 1.简单语法&#xff1a; 2.复杂语法&#xff1a; 对表操作&#xff1a; 创建表&#xff1a; 1.普…

JVM-内存结构

✅作者简介&#xff1a;热爱Java后端开发的一名学习者&#xff0c;大家可以跟我一起讨论各种问题喔。 &#x1f34e;个人主页&#xff1a;Hhzzy99 &#x1f34a;个人信条&#xff1a;坚持就是胜利&#xff01; &#x1f49e;当前专栏&#xff1a;JVM &#x1f96d;本文内容&…

《程序员的底层思维》读书笔记

人是能够习惯于任何环境的生物&#xff0c;之前你认为自己难以克服的困难&#xff0c;慢慢都会适应了。 维克多弗兰克《活出生命的意义》 文章目录 人是能够习惯于任何环境的生物&#xff0c;之前你认为自己难以克服的困难&#xff0c;慢慢都会适应了。 基础思维能力逻辑思维批…

每日学术速递5.12

CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 Subjects: cs.CV 1.ImageBind: Holistic AI learning across six modalities 标题&#xff1a;ImageBind&#xff1a;跨六种模式的整体人工智能学习 作者&#xff1a;Mengyuan Yan Jessica Lin Mont…

支付系统设计三:渠道网关设计04-渠道数据补全

文章目录 前言一、交易信息准备1. MessageDescription内容2. 交易信息填充3. 开户机构信息填充4. 省市区域信息填充5. 银行信息填充 二、路由处理三、支付渠道数据补全1.服务端支付渠道获取2. 支付渠道通用数据补全2.1 支付渠道账户信息补全2.1 商户信息补全结束 3. 支付渠道差…

具有噪声标签的鲁棒医学图像分割的点类仿射损失校正

文章目录 Joint Class-Affinity Loss Correction for Robust Medical Image Segmentation with Noisy Labels摘要本文方法Differentiated Affinity Reasoning (DAR)Class-Affinity Loss Correction (CALC)Class-Level Loss CorrectionAffinity-Level Loss CorrectionClass-Affi…