MySQL数据库,触发器、窗口函数、公用表表达式

触发器

触发器是由事件来触发某个操作(也包含INSERT、UPDATE、DELECT事件),如果定义了触发程序,当数据库执行这些语句时,就相当于事件发生了,就会自动激发触发器执行相应的操作

当对数据表中的数据执行 插入、更新和删除操作,需要自动执行一些数据库逻辑时,就可以使用触发器来实现。

触发器的创建:

格式:

例:创建触发器before_insert,向表一插入数据之前,向表二中插入日志信息。

DELIMITER $CREATE TRIGGER before_insert_triBEFORE INSERT ON test_firstFOR EACH ROWBEGININSERT INTO test_second(t_log)VALUES('before insert ……');END $DELIMITER ;

创建触发器after_insert,向表一插入数据之后,向表二中插入日志信息。

DELIMITER $CREATE TRIGGER after_insert_triAFTER INSERT ON test_firstFOR EACH ROWBEGININSERT INTO test_second(t_log)VALUES('after insert ……');END $DELIMITER ;

例:在添加员工信息时,判断员工信息是否大于他领导的薪资,如果大于,则报'HY000'的错误,使得添加失败。

-- 创建触发器DELIMITER $CREATE TRIGGER sal_check_tri2BEFORE INSERT ON emp_test_triFOR EACH ROWBEGINDECLARE mgr_sal DECIMAL(7,2);SELECT sal INTO mgr_sal FROM emp_test_triWHERE empno = NEW.mgr;IF NEW.sal > mgr_salTHEN SIGNAL SQLSTATE 'HY000' SET MESSAGE_TEXT = '薪资不能比领导高';END IF;END $DELIMITER ;-- 插入数据INSERT INTO emp_test_tri(empno,ename,mgr,sal)VALUES(8000,'Tom', 7788,2500);INSERT INTO emp_test_tri(empno,ename,mgr,sal)VALUES(8001,'Tom', 8000,3200);

注:触发器中的NEW表示当前正在添加的记录。OLD表示删除前、更新前的记录

查看触发器:

查看当前数据库的所有触发器的定义:

SHOW TRIGGERS;

查看当前数据库中某个数据库的定义:

SHOW CREATE TRIGGER 触发器名;

从系统库information_schema的TRIGGERS表中查询触发器的信息:

SELECT * FROM  information_schema.TRIGGERS;

删除触发器

DROP TRIGGER 触发器名;

窗口函数

窗口函数的作用类似于在查询中对数据进行分组。与分组操作不同的是,分组操作会把分组的结果聚合成一条记录,而窗口函数是将结果置于每一条数据记录中

例:查询员工信息,按部门分类,在每个员工前显示其所在部门的平均工资。

SELECT empno,ename,deptno,SUM(sal) OVER(PARTITION BY deptno) '部门平均工资'FROM emp;

可以发现,查询中确实对数据进行了分组,但是只是将每个组并列在了一起,然后在每个员工的后面显示其部门平均工资

窗口函数的语法格式:

函数 OVER (PARTITION BY 字段名 ORDER BY 字段名 ASC/DESC)

或者是

函数 OVER 窗口名 …… WINDOW 窗口名 AS (PARTITION BY 字段名 ORDER BY 字段名 ASC/DESC)

窗口的使用:

OVER括号中的分组排序规则的内容可以以一个窗口代替,最后在使用窗口的多个函数声明完后,用WINDOW 窗口名 AS (PARTITION BY 字段名 ORDER BY 字段名 ASC/DESC)指明窗口的具体规则的内容。

PARTITION BY子句:

指定窗口函数按照哪些字段分组,分组后,窗口函数在每个分组中分别执行

ORDER BY:

指定窗口函数按照那些字段进行排序,也是在组内排序

函数的分类:

序号函数:

ROW_NUMBER( )函数

ROW_NUMBER( )能够对数据中的序号进行顺序显示。按分组分别显示序号。

例:查看员工信息,以员工部门分组,在每个员工前显示其在部门的序号。每个部门中按员工工资排序。

SELECT ROW_NUMBER() OVER(PARTITION BY deptno ORDER BY sal) 序号,empno,ename,deptnoFROM emp;

也可以利用新生成的序号,在后面加上WHERE 序号 < 3,求出每个部门工资排名前三的员工信息。

RANK( )函数

使用RANK( )函数能够对序号进行并列排序,并且会跳过重复的序号(比如序号为1,1,3……)

例:查看员工信息,以员工部门分组,每个部门中按员工工资排序,并显示其在工资的排名(跳过重复的排名序号)。

SELECT empno,ename,deptno,RANK() OVER(PARTITION BY deptno ORDER BY sal) '部门工资排名'FROM emp;

与前面的ROW_NUMBER( )函数不同的是,当遇到相同的值比较时,会判为相同值的记录排序序号一样,并跳过重复的排序再计数。

DENSE_RANK( )函数

DENSE_RANK( )函数对序号进行并列排序并且不会跳过重复的序号(比如序号为1,1,2……)

例:查看员工信息,以员工部门分组,每个部门中按员工工资排序,并显示其在工资的排名(不跳过重复的排名序号)。

SELECT empno,ename,deptno,DENSE_RANK() OVER(PARTITION BY deptno ORDER BY sal) '部门工资排名'FROM emp;

与前面的RANK( )函数不同的是,不跳过重复的排序再计数。

分布函数:

PERCENT_RANK( )函数

PERCENT_RANK( )函数是等级值百分比函数。

计算方式:(rank - 1) / (rows - 1)

其中,rank的值是使用RANK( )函数产生的序号,rows的值为当前窗口的总记录数。

例:查看员工信息,以员工部门分组,每个部门中按员工工资排序,并显示其在工资的排名(跳过重复的排名序号),并显示其序号的等级值百分比。

SELECT empno,ename,deptno,RANK() OVER(PARTITION BY deptno ORDER BY sal) '部门工资排名',PERCENT_RANK() OVER(PARTITION BY deptno ORDER BY sal) '排名比例'FROM emp;

使用窗口的格式:

SELECT empno,ename,deptno,RANK() OVER w '部门工资排名',PERCENT_RANK() OVER w '排名比例'FROM emp WINDOW w AS (PARTITION BY deptno ORDER BY sal);

CUME_DIST( )函数

CUME_DIST( )函数主要用于查询小于或等于本记录的某个值的组内的记录的比例

例:查询工资小于或等于当前员工的薪资的员工的比例

SELECT empno,ename,sal,deptno,CUME_DIST() OVER(PARTITION BY deptno ORDER BY sal ASC) '比例'FROM emp;

以MILLER为例,在10号部门中员工工资小于或等于1300的员工比例为0.3333……

以CLARK为例,在10号部门中员工工资小于或等于2450的员工比例为0.6666……

前后函数

LAG(expr,n)函数

LAG(expr,n)函数返回当前行的第前n行记录的expr的值

例:查询上一个员工与当前员工的薪资的差值。

SELECT empno,ename,deptno,sal,pre_sal,sal - pre_sal diff_salFROM(SELECT empno,ename,deptno,sal,LAG(sal,1) OVER w pre_salFROM empWINDOW w AS (PARTITION BY deptno ORDER BY sal)) t;

子查询中的pre_sal即为上一个记录的薪资。将1改为2即为上两个记录的工资,找不到相应的记录结果为NULL。

首尾函数

FIRST_VALUES(expr)函数

FIRST_VALUES(expr)函数返回第一个记录的expr的值(分组内的第一个),会在每一行都显示第一个记录的expr的值。

例:

SELECT empno,ename,deptno,sal,FIRST_VALUE(sal) OVER(PARTITION BY deptno ORDER BY sal) '部门工资排名最高'
FROM emp;

LAST_VALUES(expr)函数

LAST_VALUES(expr)函数返回最后一个记录的expr的值

其他函数

NTH_VALUES(expr,n)函数

NTH_VALUES(expr,n)函数返回第n个记录的expr的值

NTILE(n)函数

NTILE(n)函数将分区中的有序数据分为n个桶,记录桶编号。

例:将员工按薪资分为三组。

SELECT NTILE(3) OVER w 桶编号,empno,deptno,ename,salFROM emp WINDOW w AS (PARTITION BY deptno ORDER BY sal);

即自动按薪资再分一个等级,按照要分的组数来均分等级

公用表表达式

公用表表达式(或通用表表达式)简称为CTE(Common Table Expressions)。CTE是一个命名的临时结果集,作用范围是当前语句。CTE可以理解为一个可以复用的子查询

公用表表达式分为普通公用表表达式和递归公用表表达式。

普通公用表表达式:

例:

WITH test_cteAS (SELECT DISTINCT deptno FROM emp)SELECT *FROM dept dJOIN test_cte eON d.deptno = e.deptno;

将查询结果放在WITH CTE名 AS ( )的括号中,就可以在下面的查询语句中将CTE当作一个表使用。可以有多个CTE,CTE可以引用其他CTE。

递归公用表表达式:

在WITH和CTE名中间插入RECURSIVE

例:

WITH RECURSIVE cteAS(-- 若UNION ALL前面的查询语句为A部分SELECT empno,ename,mgr,1 AS 第几代 FROM emp WHERE empno = 7839 -- 种子查询,设置第一代领导UNION ALL-- 若UNION ALL后面的查询语句为B部分SELECT a.empno,a.ename,a.mgr,第几代+1 FROM emp AS a JOIN cteON (a.mgr = cte.empno) -- 递归查询,找出以递归公用表表达式的人为领导的人,即找出A部分的下一代-- 执行完后,B部分变为新的A部分,继续找新的B部分,直到找不到任何记录为止。)SELECT empno,ename,第几代 FROM cte;-- 可以在此处加上WHERE子句,查询指定的第几代数。

A部分先设置查询的第一代,B部分再设置下一代的查询方法,当A、B执行完后,B会成为新的A部分,查找新的B部分,以此类推,直到找不到下一代记录为止。A、B部分用UNION ALL连接。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Redis——多级缓存

JVM进程缓存 为了演示多级缓存&#xff0c;这里先导入一个商品管理的案例&#xff0c;其中包含商品的CRUD功能。将来会给查询商品添加多级缓存。 导入Demo数据 1.安装mysql 后期做数据同步需要用到MySQL的主从功能&#xff0c;所以需要在虚拟机中&#xff0c;利用Docker来运…

任务十六:主备备份型防火墙双机热备

目录 目的 器材 拓扑 步骤 一、基本配置 配置各路由器接口的IP地址【省略】 1、配置BGP协议实现Internet路由器之间互联 2、防火墙FW1和FW2接口IP配置与区域划分 3、配置区域间转发策略 4、配置NAPT和默认路由 5、配置VRRP组&#xff0c;并加入Active/standby VGMP管…

图片转excel:二种合并方式,有何区别?

图片怎么转为可编辑的excel&#xff0c;并且将转换结果合并为一个表&#xff1f;打开眼精星表格文字识别电脑客户端&#xff0c;我们可以看到顶部有一个功能&#xff0c;名为“表格合并”&#xff0c;而在表格识别模块提交选项里&#xff0c;我们会发现有“合并”选项&#xff…

什么是关键词排名蚂蚁SEO

关键词排名是指通过搜索引擎优化&#xff08;SEO&#xff09;技术&#xff0c;将特定的关键词与网站相关联&#xff0c;从而提高网站在搜索引擎中的排名。关键词排名对于网站的流量和用户转化率具有至关重要的影响&#xff0c;因此它是SEO工作中最核心的部分之一。 如何联系蚂…

C# WPF上位机开发(usb设备访问)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 目前很多嵌入式设备都支持usb访问&#xff0c;特别是很多mcu都支持高速usb访问。和232、485下个比较&#xff0c;usb的访问速度和它们基本不在一个…

微软近日推出了Phi-2,这是一款小型语言模型,但其性能却十分强大

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

redis各种数据类型的应用场景

String应用场景 单值缓存 SET key value GET key 对象缓存 SET user:1 value(json格式数据)MSET user:1:name zhuge user:1:balance 1888 MGET user:1:name user:1:balance 分布式锁 SETNX product:10001 true //返回1代表获取锁成功 …

iPhone 17Pro/Max或升级4800万像素长焦镜头,配备自研Wi-Fi 7芯片。

iPhone 16未至&#xff0c;关于iPhone 17系列的相关消息就已经放出&#xff0c;到底是谁走漏了风声。 海通国际证券技术分析师Jeff Pu近日发布报告称&#xff0c;苹果将为2025年推出的iPhone 17ProMax配备4800万像素的长焦镜头。经调查&#xff0c;该分析师认为提升iPhone拍摄方…

【百度PARL】强化学习笔记

文章目录 强化学习基本知识一些框架Value-based的方法Q表格举个例子 强化的概念TD更新 Sarsa算法SampleSarsa Agent类 On_policy vs off_policy函数逼近与神经网络DQN算法DQN创新点DQN代码实现model.pyalgorithm.pyagent.py总结&#xff1a;举个例子 实战 视频&#xff1a;世界…

centos安装opencv并在springboot中使用

使用conda安装opencv&#xff0c;并在docker运行的容器中使用&#xff0c;这里以运行则springboot应用的容器为例 步骤一&#xff1a;安装 在conda中安装 # 安装依赖 conda install numpy matplotlib# 安装opencv conda install -c conda-forge opencv # 或者制定版本 conda…

AI创作系统ChatGPT网站源码,支持AI绘画,支持GPT语音对话+智能思维导图生成

一、前言 SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI创作Ch…

开发企业展示小程序的关键步骤和技巧

随着移动互联网的快速发展&#xff0c;小程序已经成为企业展示形象、推广产品和服务的重要工具。拥有一个优秀的小程序可以帮助企业提高品牌知名度&#xff0c;吸引更多潜在客户&#xff0c;提升用户体验。以下是拥有一个展示小程序的步骤&#xff1a; 确定需求和目标 首先&am…