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

触发器

触发器是由事件来触发某个操作(也包含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.mfbz.cn/a/255239.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

进制之间的转换——n进制转换为m进制(C/C++实现,简单易懂)

目录 &#x1f308;前言&#xff1a; &#x1f4c1; 什么是进制转换&#xff1a; &#x1f4c1;其他进制转换成十进制&#xff1a; &#x1f4c2;二进制( B ) ——> 十进制( D ) &#x1f4c2;八进制( O ) ——> 十进制( D ) &#x1f4c2;十六进制( H ) ——> 十进制…

visual stdio code运行vue3

npm init vuelatest 该命令初始化vue项目 使用visual stdio code创建vue项目 ,这边是vue-project文件夹 vs code打开项目 vscode操作vue项目 vscode操作vue项目

数据分析思维导图

参考&#xff1a; https://zhuanlan.zhihu.com/p/567761684?utm_id0 1、数据分析步骤地图 2、数据分析基础知识地图 3、数据分析技术知识地图 4、数据分析业务流程 5、数据分析师能力体系 6、数据分析思路体系 7、电商数据分析核心主题 8、数据科学技能书知识地图 9、数据挖掘…

设计模式 简单工厂 工厂方法模式 抽象工厂模式 Spring 工厂 BeanFactory 解析

工厂模式介绍 工厂模式是我们最常用的实例化对象模式了&#xff0c;是用工厂方法代替new操作的一种模式。它是创建型模式。 简单工厂 简单工厂模式是指由一个工厂对象决定创建出哪一种产品类的实例, 但它不属于GOF 23种设计模式 简单工厂适用于工厂类负责创建的对象较少的场景,…

Spring IOC—基于注解配置和管理Bean 万字详解(通俗易懂)

目录 一、前言 二、基于注解配置Bean 1.基本介绍 : 2.应用实例 : 3.注意事项 : 三、手动实现Spring 注解配置机制 1.需求 : 2.思路 : 3.实现 : 3.1 自定义注解类 3.2 自定义配置类 3.3 自定义容器类 3.4 在测试类中进行测试 四、自动装配 0.总述 : 1.AutoWired自动装…

Autosar DEM DTC的Debounce策略

文章目录 简介Debounce策略1、基于计数器的 Debounce 策略2、基于时间的Debounce策略 简介 故障事件防抖&#xff0c;与按键防抖&#xff08;软件需要延时确认按键不是误触发&#xff09;的作用类似&#xff0c;目的是为了防止事件误触发采取的策略。 因为DTC并不是一达到触发…

Transformer Decoder的输入

大部分引用参考了既安的https://www.zhihu.com/question/337886108/answer/893002189这篇文章&#xff0c;个人认为写的很清晰&#xff0c;此外补充了一些自己的笔记。 弄清楚Decoder的输入输出&#xff0c;关键在于图示三个箭头的位置&#xff1a; 以翻译为例&#xff1a; 输…

2023.12.16 关于 分布式系统 基本介绍

目录 单机架构 服务器负载过高问题 解决方法 分布式系统 引入更多的服务器节点 负载均衡 数据库读写分离 引入缓存 数据库分库分表 引入微服务 基本概念 应用&#xff08;Application&#xff09;/ 系统&#xff08;System&#xff09; 模块&#xff08;Modul…

力扣日记12.18-【二叉树篇】合并二叉树

力扣日记&#xff1a;【二叉树篇】合并二叉树 日期&#xff1a;2023.12.18 参考&#xff1a;代码随想录、力扣 617. 合并二叉树 题目描述 难度&#xff1a;简单 给你两棵二叉树&#xff1a; root1 和 root2 。 想象一下&#xff0c;当你将其中一棵覆盖到另一棵之上时&#xf…

软件测试培训三个月,想找到工作,到底应该怎么搞

功能方面&#xff1a;问的最多的就是测试流程&#xff0c;测试计划包含哪些内容&#xff0c;公司人员配置&#xff0c;有bug开发认为不是 bug怎么处理&#xff0c;怎样才算是好的用例&#xff0c;测试用例设计方法&#xff08;等价类&#xff0c;边界值等概念方法&#xff09;&…

C# 使用FluentHttpClient请求WebApi

写在前面 FluentHttpClient 是一个REST API 异步调用 HTTP 客户端&#xff0c;调用过程非常便捷&#xff0c;采用流式编程&#xff0c;可以将所有请求所需的参数一次性发送&#xff0c;并直接获取序列化后的结果。 老规矩从NuGet上安装该类库&#xff1a; 这边一定要认准是 P…

python/c++ Leetcode题解——1.两数之和

目录 方法1:枚举法 思路 Code 方法2:哈希表 思路 Code 方法1:枚举法 思路 最容易想到的方法是枚举数组中的每一个数 x&#xff0c;寻找数组中是否存在 target - x。 当我们使用遍历整个数组的方式寻找 target - x 时&#xff0c;需要注意到每一个位于 x 之前的元素都已…

使用GPU利用ffmpeg-在Pyhton代码中实现视频转码到MP4格式的过程记录【失败告终-原因是显示型号太老不支持】

01-安装Nvida的显卡驱动和CUDA 参考文章 https://blog.csdn.net/wenhao_ir/article/details/125253533 进行安装。 02-下载ffmpeg的可执行文件 下载ffmpeg的Windows可执行文件&#xff0c;下载页面&#xff1a; https://www.gyan.dev/ffmpeg/builds/#release-builds 我在202…

深度学习中的潜在空间

1 潜在空间定义 Latent Space 潜在空间&#xff1a;Latent &#xff0c;这个词的语义是“隐藏”的意思。“Latent Space 潜在空间”也可以理解为“隐藏的空间”。Latent Space 这一概念是十分重要的&#xff0c;它在“深度学习”领域中处于核心地位&#xff0c;即它是用来学习…

ROS机器人入门

http://www.autolabor.com.cn/book/ROSTutorials/ 1、ROS简介 ROS 是一个适用于机器人的开源的元操作系统。其实它并不是一个真正的操作系统&#xff0c;其 底层的任务调度、编译、寻址等任务还是由 Linux 操作系统完成&#xff0c;也就是说 ROS 实际上是运 行在 Linux 上的次级…

微信小程序开发学习(基础)

学习课程&#xff1a;2023最新零基础入门微信小程序开发_哔哩哔哩_bilibili 微信开发工具下载地址&#xff1a;微信开发者工具下载地址与更新日志 | 微信开放文档 开发文档&#xff1a;微信开放文档 创建新项目 机型&#xff1a;iPhoneX 快捷键 <view>.row{$}*8 <…

Android hilt使用

一&#xff0c;添加依赖库 添加依赖库app build.gradle.kts implementation("com.google.dagger:hilt-android:2.49")annotationProcessor("com.google.dagger:hilt-android:2.49")annotationProcessor("com.google.dagger:hilt-compiler:2.49"…

对偶问题笔记(1)

目录 1 从 Lagrange 函数引入对偶问题2. 强对偶性与 KKT 条件3. 对偶性的鞍点特征 1 从 Lagrange 函数引入对偶问题 考虑如下优化问题 { min ⁡ f 0 ( x ) s . t f i ( x ) ≤ 0 , i 1 , ⋯ , p , h j ( x ) 0 , j 1 , ⋯ , q , x ∈ Ω , \begin{align} \begin{cases}\min…

Pipelined-ADC设计一:序言

现在是2023年12月18日&#xff0c;准备开新帖&#xff0c;设计一个 流水线型 模数转换器&#xff08; Pipelined-ADC &#xff09;。记录帖&#xff0c;后续会放在咸鱼。同步记录&#xff0c;谨防盗用。 初定指标&#xff1a;12位50Mhz&#xff0c;采用2.5bit每级结构&#xff…

奇数魔方阵

魔方阵的生成方法为第0行中间位置为1 2开始的其余n*n-1个数&#xff0c;依次按以下规则存放 1.下一个元素存放在当前元素的上一行、下一列 2.如果上一行下一列已有元素&#xff0c;则下一个元素存放的位置为当前列的下一行 3.在找上一行、下一行或下一列的时候&#xff0c;把矩…
最新文章