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

news2025/1/12 15:56:54

触发器

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

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

触发器的创建:

格式:

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

DELIMITER $

CREATE TRIGGER before_insert_tri

BEFORE INSERT ON test_first

FOR EACH ROW

BEGIN

INSERT INTO test_second(t_log)

VALUES('before insert ……');

END $

DELIMITER ;

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

DELIMITER $

CREATE TRIGGER after_insert_tri

AFTER INSERT ON test_first

FOR EACH ROW

BEGIN

INSERT INTO test_second(t_log)

VALUES('after insert ……');

END $

DELIMITER ;

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

-- 创建触发器

DELIMITER $

CREATE TRIGGER sal_check_tri2

BEFORE INSERT ON emp_test_tri

FOR EACH ROW

BEGIN

DECLARE mgr_sal DECIMAL(7,2);

SELECT sal INTO mgr_sal FROM emp_test_tri

WHERE empno = NEW.mgr;

IF NEW.sal > mgr_sal

THEN 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,deptno

FROM 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_sal

FROM(

            SELECT empno,ename,deptno,sal,LAG(sal,1) OVER w pre_sal

            FROM emp

            WINDOW 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,sal

FROM emp WINDOW w AS (PARTITION BY deptno ORDER BY sal);

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

公用表表达式

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

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

普通公用表表达式:

例:

WITH test_cte

AS (SELECT DISTINCT deptno FROM emp)

SELECT *

FROM dept d

JOIN test_cte e

ON d.deptno = e.deptno;

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

递归公用表表达式:

在WITH和CTE名中间插入RECURSIVE

例:

WITH RECURSIVE cte

AS

(

-- 若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 cte

ON (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.coloradmin.cn/o/1320723.html

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

相关文章

AX7A200教程(9): ov5640摄像头输出显示720p视频

一&#xff0c;功能框图 ov5640摄像头视频通过ddr3缓存后&#xff0c;最后使用hdmi接口进行输出显示 二&#xff0c;摄像头硬件说明 2.1&#xff0c;像头硬件管脚 如下图所示&#xff0c;一共18个管脚 2.2&#xff0c;摄像头电源初始化时序 因这个ov5640摄像头是买的老摄像…

“去 Android化”为何蔚然成风?

早在2008年时&#xff0c;国内市场诞生了第一批自研手机OS&#xff0c;由于种种缘由铩羽而归&#xff0c;“优化Android ”貌似成为了本土特色。而从2023年下半年开始掀起了一股"去安卓化"的热潮&#xff0c;像华为、小米、vivo等都不约而同的站在了同一战线。 “去…

Kotlin Multiplatform的现状—2023年网络研讨会

Kotlin Multiplatform的现状—2023年网络研讨会 在2023年&#xff0c;Kotlin Multiplatform因其开发、当前状态和未来潜力而受到了相当大的关注。随着越来越多的开发者对采用KMP进行跨平台解决方案表示兴趣&#xff0c;JetBrains在11月下旬推出了一系列网络研讨会作为回应。首…

数字化转型三大证书推荐:TOGAF+ITIL4+DAMA

&#x1f308;数字化转型是企业发展的必经之路。通过数字化的手段&#xff0c;有效提升企业业务开展及内部运营的效率&#xff0c;利于企业的降本增效及流程再造。 目前关于数字化转型的培训学习越来越多&#xff0c;对于推动企业数字化转型起到了重要作用。 数字化转型三大证书…

css+html横向滚动+固定宽

没什么好说的&#xff0c;快上代码&#xff01; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Do…

滴灌广袤农村——建行江门市分行多维施策惠乡村

江门是全省农业大市、海洋大市&#xff0c;县域面积辽阔&#xff0c;约占全市95%&#xff0c;总人口和GDP约占7成左右&#xff0c;为建行江门市分行服务乡村振兴提供“沃土”。建行江门市分行以新金融行动贯彻新发展理念&#xff0c;主动作为&#xff0c;以数字技术赋能乡村振兴…

竞赛保研 python的搜索引擎系统设计与实现

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; python的搜索引擎系统设计与实现 &#x1f947;学长这里给一个题目综合评分(每项满分5分) 难度系数&#xff1a;3分工作量&#xff1a;5分创新点&#xff1a;3分 该项目较为新颖&#xff…

域名接入CloudFlare

接入Cloudflare分为两步 Cloudflare中注册站点域名DNS修改 整个过程如下 1.) 访问Cloudflare面板&#xff0c;添加站点 2.) 选择免费版 3.) 查看并明确DNS记录&#xff0c;其中服务的解析地址填写自己实际的服务器ip 4.) 去域名管理控制台&#xff0c;移除旧DNS服务器&#…

Spring Cloud:Eureka

目录 一、Eureka介绍 1.Eureka的作用 2.总结 二.搭建Eureka服务端步骤 1.导入maven依赖 2.编写启动类&#xff0c;添加EnableEurekaServer注解 3.添加application.yml文件&#xff0c;编写下面的配置&#xff1a; 三.注册Eureka客户端服务提供者&#xff08;user-servic…

从 0 开始创建 SpringBoot 项目

从 0 开始创建 SpringBoot 项目 从 0 开始创建 SpringBoot 项目环境准备创建项目项目目录结构及说明编写代码参考 从 0 开始创建 SpringBoot 项目 环境准备 操作系统&#xff1a;Windows 10IDE&#xff1a;IntelliJ IDEA 2023.3.1Java 版本&#xff1a;jdk1.8 工具网盘链接&…

Maven下载及安装自用版

Maven下载及安装自用版 可能是Maven用久了。感觉Maven用起来还算顺手&#xff0c;比Gradle要好上手一些。 一、下载 Maven 下载地址 注意下载版本和依赖要求&#xff0c;下载后&#xff0c;解压放在指定的位置;注意安装地址&#xff0c;放在自己规划好的开发环境专用文件夹里…

三菱plc学习入门(一,认识三菱plc)

今天就开始对三菱的plc软件入一个门&#xff0c;希望小编的文章对读者和初学者有所帮助&#xff01;欢迎评论指正&#xff0c;废话不多说&#xff0c;下面开始学习。 目录 plc的型号介绍 M表示什么&#xff1f; T表示什么&#xff1f; R表示什么&#xff1f; 为什么三菱没…

创建自定义 gym env 教程

gym-0.26.1 pygame-2.1.2 自定义环境 GridWolrdEnv 教程参考 官网自定义环境 &#xff0c;我把一些可能有疑惑的地方讲解下。 首先整体文件结构, 这里省略了wrappers gym-examples/main.py # 这个是测试自定义的环境setup.py gym_examples/__init__.pyenvs/__init__.pygri…

机器学习 | SVM支持向量机

欲穷千里目&#xff0c;更上一层楼。 一个空间的混乱在更高维度的空间往往意味着秩序。 Machine-Learning: 《机器学习必修课&#xff1a;经典算法与Python实战》配套代码 - Gitee.com 1、核心思想及原理 针对线性模型中分类两类点的直线如何确定。这是一个ill-posed problem。…

【Docker光速搞定深度学习环境配置!】

你是否还在用压缩包打包你的代码&#xff0c;然后在新的机器重新安装软件&#xff0c;配置你的环境&#xff0c;才能跑起来&#xff1f; 特别有这样的情况&#xff1a;诶&#xff0c;在我电脑跑的好好的&#xff0c;怎么这里这么多问题&#xff1f; 当项目比较简单的时候&am…

接口自动化测试框架【AIM】

最近在做公司项目的自动化接口测试&#xff0c;在现有几个小框架的基础上&#xff0c;反复研究和实践&#xff0c;搭建了新的测试框架。利用业余时间&#xff0c;把框架总结了下来。 AIM框架介绍 AIM&#xff0c;是Automatic Interface Monitoring的简称&#xff0c;即自动化…

Idea代码走查工具FindBus使用以及缺陷分析

1. 简介 Findbugs是一个静态分析工具&#xff0c;它检查类或者jar文件&#xff0c;将字节码与一组缺陷模式进行对比以发现可能的问题。利用这个工具可以在不实际运行程序的情况下对软件进行分析。可以帮助改进代码质量。Findbugs提供了方便操作的可视化界面&#xff0c;同时&a…

[计网00] 计算机网络开篇导论

目录 前言 计算机网络的概念 计算机网络的分层 计算机网络的分类 网络的标准化工作和相关组织 计算机网络的性能指标 前言 计算机网络在我们的日常生活中无处不在 在网络会有各种各样的协议和封装 保证我们的信息完整,无误的在各个客户端之前传输 计算机网络的概念 四…

Unity与Android交互通信系列(2)

在上一篇文章中&#xff0c;我们介绍了Unity和Android交互通信的原理及在Unity中直接调用Java代码的方式&#xff0c;但没有给出代码示例&#xff0c;下面通过实际例子演示上篇文章中AndroidJavaClass、AndroidJavaObject两个类的基本用法&#xff0c;由于交互通信涉及到两端&a…

1KW逆变器UPS纯正弦波方案

硬件方案--110V方案 本套逆变器方案分110V输出以及220V输出&#xff0c;电池最大电压是48V&#xff0c;包括了LCD。110V方案主控使用的dsp是MICROCHIP(美国微芯)的dsPIC33FJ16GS504芯片&#xff0c;ACDC控制器是TOP250YN&#xff0c;运算放大器包含LM358、MCP6022&#xff0c;电…