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, -- 订单idprice 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 payTypewhen 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 rnfrom 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)进行计算。其中,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 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,则进行排序混乱,会出现错误的结果
selectdname,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):
返回窗口中第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
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;
(日常美图时间)
相关文章:

MySQL---控制流函数、窗口函数(序号函数、开窗聚合函数、分布函数、前后函数、头尾函数、其他函数)
1. 控制流函数 格式 解释 案例 IF(expr,v1,v2) 如果表达式 expr 成立,返回结果 v1;否则,返回结果 v2。 SELECT IF(1 > 0,正确,错误) ->正确 IFNULL(v1,v2) 如果 v1 的值不为 NULL,则返回 v1ÿ…...

一心报国的西工大网安人走出新手村
大二下学期5月5日晚上,西工大长安校区教学西楼,作为一名网安专业本科生,从大一便立志学好网安知识,报效祖国,却苦于没有优秀学习资源,就把这事儿拖到了大二,最近上了一门专业课,如同…...
如何安装oracle的sample schema
首先从如下的地址选择合适的版本进行下载 https://github.com/oracle-samples/db-sample-schemas/releases 如果是rac环境,最好是将这个数据库停掉,然后只启动一个instance,然后再开始安装 [Tue May 09 20:26:34][377951][oraclenshqae01adm…...

ChatGPT :国内免费可用 ChatGPT +Midjourney绘图
前言 ChatGPT(全名:Chat Generative Pre-trained Transformer),美国OpenAI 研发的聊天机器人程序 ,于2022年11月30日发布 。ChatGPT是人工智能技术驱动的自然语言处理工具,它能够通过理解和学习人类的语言来…...

女孩子转数据分析难吗?难在哪里?
对于数据分析,很多人乍一听会觉得没啥技术难度,是个适合女孩子的专业。我们面对很多零基础小白也是用通俗的语言来形容这个专业:一般是通过Excel或者power BI工具对数据进行分析,制作成可视化的报表给领导层,为公司业务…...

基于常用设计模式的业务框架
前言 做开发也有好几年时间了,最近总结和梳理自己在工作中遇到的一些问题,工作中最容易写出BUG的需求就是改造需求了。一个成熟的业务系统是需要经过无数次迭代而成的,也意味着经过很多开发人员之手,最后到你这里,大部…...

ubuntu重启ssh服务
一、开启ssh服务首先需要安装打开ssh服务的库: sudo apt-get install openssh-server 二、检查当前的ssh开启情况: ps -e |grep ssh 三、如果有sshd,则ssh-server已经启动;若仅有agent,则尚未启动; 开启ssh…...

【19】SCI易中期刊推荐——计算机 | 人工智能领域(中科院2区)
💖💖>>>加勒比海带,QQ2479200884<<<💖💖 🍀🍀>>>【YOLO魔法搭配&论文投稿咨询】<<<🍀🍀 ✨✨>>>学习交流 | 温澜潮生 | 合作共赢 | 共同进步<<<✨✨ 📚📚>>>人工智能 | 计算机视觉…...
Vue.js条件、循环语句
文章目录 条件语句v-ifv-elsev-else-ifv-show 循环语句v-for 指令v-for 迭代对象valuevalue ,keyvalue ,key,index v-for 迭代整数 条件语句 v-if 在元素 和 template 中使用 v-if 指令 <div id"app"><p v-if"seen">现在你看到我…...

Go语言学习查缺补漏ing Day4
Go语言学习查缺补漏ing Day4 一、掌握iota的使用 请看下面这段代码: package mainimport "fmt"const (a iota_bc "ReganYue"dd1e iotaf iota )func main() {fmt.Println(a, b, c, d, d1, e, f) }思考一下输出结果会是什么? …...

说服审稿人,只需牢记这 8 大返修套路!
本文作者:雁门飞雪 如果说科研是一场修炼,那么学术界就是江湖,投稿就是作者与审稿人或编辑之间的高手博弈。 在这一轮轮的对决中,有时靠的是实力,有时靠的是技巧,然而只有实力和技巧双加持的作者才能长久立…...

Java 责任链模式详解
责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它用于将请求的发送者和接收者解耦,使得多个对象都有机会处理这个请求。在责任链模式中,有一个请求处理链条,每个处理请求的对象都是一个…...

使用MASA全家桶从零开始搭建IoT平台(三)管理设备的连接状态
文章目录 前言分析方案1:遗嘱消息演示遗嘱消息的使用实施流程 方案2:使用WebHook开启WebHook演示Webhook编写代码 前言 获取一个设备的在线和离线状态,是一个很关键的功能。我们对设备下发的控制指令,设备处于在线状态才能及时给我们反馈。这里的在线和…...

我的新书上架了!
talk is cheap,show you my book! 新书《从0开始学ARM》终于在各大平台上架了!! 一、关于本书 1. 本书主要内容 ARM体系架构是目前市面上的主流处理器体系架构,在手机芯片和嵌入式芯片领域,ARM体系架构…...

语言与专业的奇迹:如何利用ChatGPT优化跨国贸易
贸易公司,在进行跨国贸易时,往往需要面对不同国家的甲方或者乙方,在与之沟通的过程中,语言和专业是必须要过的一关,顺畅的交流,往往会带来更好的收益。 今天以“茶”为例,给大家介绍一“知否AI…...

云服务器安装宝塔Linux面板命令脚本大全
阿里云服务器安装宝塔Linux面板,操作系统不同安装命令脚本也不同,支持CentOS、Alibaba Cloud Linux、Ubuntu/Deepin等Linux系统,阿里云服务器网分享阿里云服务器安装宝塔Linux面板命令脚本大全: 云服务器安装宝塔Linux面板命令 …...

zed2i相机中imu内参的标定及外参标定
zed2i中imu内参的标定 参考: https://blog.csdn.net/weixin_42681311/article/details/126109617 https://blog.csdn.net/weixin_43135184/article/details/123444090 值得注意,imu内参的标定其实不是那么重要,大致上给一个值应该影响不大…...
Java中的JUnit是什么?如何使用JUnit进行单元测试
JUnit是Java中最流行的单元测试框架之一。它可以帮助开发人员在代码编写过程中检测出错误和异常,从而提高代码的质量和可靠性。 什么是JUnit? JUnit是一个由Kent Beck和Erich Gamma创建的开源Java单元测试框架,它已经成为Java开发中最常用的…...

【seata的部署和集成】
seata的部署和集成 seata的部署和集成一、部署Seata的tc-server1.下载2.解压3.修改配置4.在nacos添加配置5.创建数据库表6.启动TC服务 二、微服务集成seata1.引入依赖2.修改配置文件 三、TC服务的高可用和异地容灾1.模拟异地容灾的TC集群2.将事务组映射配置到nacos3.微服务读取…...

uniapp学习日记之request自定义请求头
uniapp学习日记之request自定义请求头 在学习uniapp的过程中,由于笔者是从Vue项目转来学习uniapp,在使用uni.request时,发现在浏览器调试时,无法在请求头header中添加token字段,愤而弃之,便开始使用axios组…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...

使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...

GruntJS-前端自动化任务运行器从入门到实战
Grunt 完全指南:从入门到实战 一、Grunt 是什么? Grunt是一个基于 Node.js 的前端自动化任务运行器,主要用于自动化执行项目开发中重复性高的任务,例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...
解决:Android studio 编译后报错\app\src\main\cpp\CMakeLists.txt‘ to exist
现象: android studio报错: [CXX1409] D:\GitLab\xxxxx\app.cxx\Debug\3f3w4y1i\arm64-v8a\android_gradle_build.json : expected buildFiles file ‘D:\GitLab\xxxxx\app\src\main\cpp\CMakeLists.txt’ to exist 解决: 不要动CMakeLists.…...

FFmpeg avformat_open_input函数分析
函数内部的总体流程如下: avformat_open_input 精简后的代码如下: int avformat_open_input(AVFormatContext **ps, const char *filename,ff_const59 AVInputFormat *fmt, AVDictionary **options) {AVFormatContext *s *ps;int i, ret 0;AVDictio…...

解析“道作为序位生成器”的核心原理
解析“道作为序位生成器”的核心原理 以下完整展开道函数的零点调控机制,重点解析"道作为序位生成器"的核心原理与实现框架: 一、道函数的零点调控机制 1. 道作为序位生成器 道在认知坐标系$(x_{\text{物}}, y_{\text{意}}, z_{\text{文}}…...

轻量级Docker管理工具Docker Switchboard
简介 什么是 Docker Switchboard ? Docker Switchboard 是一个轻量级的 Web 应用程序,用于管理 Docker 容器。它提供了一个干净、用户友好的界面来启动、停止和监控主机上运行的容器,使其成为本地开发、家庭实验室或小型服务器设置的理想选择…...

Python环境安装与虚拟环境配置详解
本文档旨在为Python开发者提供一站式的环境安装与虚拟环境配置指南,适用于Windows、macOS和Linux系统。无论你是初学者还是有经验的开发者,都能在此找到适合自己的环境搭建方法和常见问题的解决方案。 快速开始 一分钟快速安装与虚拟环境配置 # macOS/…...