首页 > 数据库 >mysql对结果集进行遍历(mysql双重for循环如何写)

mysql对结果集进行遍历(mysql双重for循环如何写)

时间:2024-10-20 20:34:26浏览次数:5  
标签:currentValue 遍历 双重 DECLARE mysql report type id oid

原文链接:mysql对结果集进行遍历(mysql双重for循环如何写) – 每天进步一点点

0.背景

有这么一个需求:对以下的类型结果集进行更新。

更新的原则是type为c的currentValue的值= (type为b的currentValue) / ((type为b的currentValue) + (type为a的currentValue)) *100。

上面这个需求有很多种实现方法,看到这个需求的时候,我想到的双重for循环:先查询第一个结果集,第一个结果集合里面包含oid字段。

然后对第一个结果集进行遍历,把oid作为参数更新到第二个sql语句中进行更新。

本文是用定义存储过程的方式实现对结果集的遍历,也就是我所希望的双重for循环。

工具:navicat。

数据:

1 2 3 4 5 6 7 8 DROP TABLE IF EXISTS `report_data`; CREATE TABLE `report_data` (   `id` int(255) NOT NULL,     `oid` int(255) NOT NULL,   `type` varchar(10)  not NULL,   `currentValue` double not NULL,   PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
1 2 3 4 5 6 7 8 INSERT INTO `report_data` (`id`, `oid`, `type`, `currentValue`) VALUES (1, 1, 'a', 1); INSERT INTO `report_data` (`id`, `oid`, `type`, `currentValue`) VALUES (2, 1, 'b', 2); INSERT INTO `report_data` (`id`, `oid`, `type`, `currentValue`) VALUES (3, 1, 'c', 3); INSERT INTO `report_data` (`id`, `oid`, `type`, `currentValue`) VALUES (4, 1, 'd', 4); INSERT INTO `report_data` (`id`, `oid`, `type`, `currentValue`) VALUES (5, 2, 'a', 5); INSERT INTO `report_data` (`id`, `oid`, `type`, `currentValue`) VALUES (6, 2, 'b', 6); INSERT INTO `report_data` (`id`, `oid`, `type`, `currentValue`) VALUES (7, 2, 'c', 7); INSERT INTO `report_data` (`id`, `oid`, `type`, `currentValue`) VALUES (8, 2, 'd', 8);
1.对查询结果进行遍历

先展示结果模板:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 CREATE PROCEDURE [存储过程名称()] BEGIN         DECLARE s int DEFAULT 0;     DECLARE [变量名 1 ] INT DEFAULT 0;     DECLARE [变量名 2 ] VARCHAR ( 255 );     DECLARE [游标名] CURSOR FOR [包含结果集的 SQL ]         DECLARE CONTINUE HANDLER FOR NOT FOUND SET s=1;     OPEN [游标名];     FETCH [游标名] INTO [变量名 1 ],[变量名 2 ];     WHILE s <> 1 DO         [你想操作的 SQL语句 ]     FETCH [游标名] INTO [变量名 1 ],[变量名 2 ];     END WHILE; CLOSE [游标名]; END;

说明:

1.CREATE PROCEDURE [存储过程名称()] 表示创建一个存储过程。我们这里假设名称叫processdata,那么这行代码就写成 CREATE PROCEDURE processdata()

2. BEGIN 和 END 是函数的开始和结束

3.

DECLARE	[变量名 1 ] INT DEFAULT 0;
DECLARE	[变量名 2 ] VARCHAR ( 255 );

这两行代码是定义变量,为什么要定义变量呢,是因为我们查询出的结果集要放到变量中进行二次操作。这里需要注意的是,变量名的命名规则除了跟普通变量一样以外,还不能够跟结果集中对应的字段名重复。比如 select id,name from student;这个sql中有两个字段,id和name。那么定义变量的时候就不要再定义id和name了。可以换成idTemp 和nameTemp。

另外,变量的类型要和查询结果集的字段类型对应。

DECLARE s int DEFAULT 0; 这行sql比较特别是定义循环变量s的,下面的while循环要用到。

4.

DECLARE [游标名] CURSOR FOR [包含结果集的 SQL ] 

这行sql就是定义游标,其中包含了我们的结果集,比如下面这样:

DECLARE stu CURSOR FOR select id,name from student group by id;

这样的话,我们第一个结果集就出来了。后面就考虑遍历这个结果集。

5.DECLARE CONTINUE HANDLER FOR NOT FOUND SET s=1; 声明当游标遍历完后将标志变量置成某个值

6. OPEN [游标名]; 这个不用过多解释,上面定义完游标后,这里打开游标。

7.FETCH [游标名] INTO [变量名 1 ],[变量名 2 ]; 这段sql是将我们查询的结果集与我们定义的变量进行关联,注意顺序应该一一对应。比如下面这样

FETCH stu INTO idTemp,nameTemp;

这里的idTemp就表示上面结果集中的id,nameTemp就表示上面结果集中的nameTemp

8.

WHILE s <> 1 DO
....
END WHILE;

这段代码是while循环。

9.

[你想操作的sql语句]

这个地方就是内部for循环了,比如我们在这个地方写一个update语句。

update student set score=’91’ where id=idTemp and name = nameTemp;

这个语句就会去寻找上方结果集中的id和name,然后把值代入到idTemp中和nameTemp中,进行操作。

10.

FETCH [游标名] INTO [变量名 1 ],[变量名 2 ];

这段表示将游标中的值再赋值给变量,供下次循环使用。

当定义完了以后,执行sql。然后就是navicat的函数,找个我们刚才定义的函数进行执行。

2.完成需求

上面已经说明白了整个过程的含义,下面我们来完成本文的需求。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 CREATE PROCEDURE processData() BEGIN DECLARE s int DEFAULT 0; DECLARE oidTemp int DEFAULT 20; DECLARE report CURSOR FOR  SELECT oid from report_data  GROUP BY oid; DECLARE CONTINUE HANDLER FOR NOT FOUND SET s=1;     open report;     fetch report into oidTemp;     while s<>1 do             SET @fenzi=   (SELECT currentValue from report_data WHERE type='b' and oid =oidTemp);       set @fenmu=   (SELECT currentValue from report_data WHERE type='a' and oid =oidTemp) +                                     (SELECT currentValue from report_data WHERE type='b' and oid =oidTemp);             set  @result =  @fenzi/@fenmu *100;                            update report_data set currentvalue = @result WHERE oid =oidTemp and type='c';         fetch report into  oidTemp;     end while;     close report; END;

结果

本文链接:https://www.longkui.site/mysql/mysqlfor/5403/

标签:currentValue,遍历,双重,DECLARE,mysql,report,type,id,oid
From: https://www.cnblogs.com/longkui-site/p/18487826

相关文章

  • count(*)、count(1)哪个更快?面试必问:通宵整理的十道经典MySQL必问面试题
    一、你是如何理解Count(*)和Count(1)的?这两个并没有区别,不要觉得count()会查出全部字段,而count(1)不会。所以count()会更慢,你觉得MySQL作者会这么做吗?可以很明确地告诉你们count()和count(1)是一样的,而正确有区别的是count(字段)。如果你count()的是具体的字段,那......
  • 【MySQL】子查询,合并查询
    目录1.子查询1.1.单行子查询1.2.多行子查询1.3.多列子查询 1.4.在from子句里面使用子查询 2.合并查询 1.子查询         子查询,也称为嵌套查询或子选择,是SELECT嵌入在另一个SQL查询的 WHERE 或 HAVING子句中的查询。子查询返回的数据由外部语句使用......
  • ubuntu 安装 MySql5.7(基于ARM架构 源码安装)
    1系统需求目标安装MySql5.7版本。系统环境:oracle云主机,arm架构确认主机架构如下图:查看是否有5.7版本的源apt-cachesearchmysql|grepmysql-server执行后发现只有8.0版本的,5.7版本只能通过源码安装了。 2下载MySql源码下载源码要选择合适的版本,官网下载地址......
  • 使用MySQL之创建计算字段
    1.创建计算字段存储在数据库表中的数据一般不是应用程序所需要的格式。下面举几个例子。如果想在一个字段中既显示公司名,又显示公司的地址,但这两个信息一般包含在不同的表列中。城市、州和邮政编码存储在不同的列中(应该这样),但邮件标签打印程序却需要把它们作为一个恰当格......
  • 使用MySQL之用正则表达式进行搜索
    1.正则表达式介绍正则表达式是用来匹配文本的特殊的串(字符集合)。如果你想从一个文本文件中提取电话号码,可以使用正则表达式。如果你需要查找名字中间有数字的所有文件,可以使用一个正则表达式。如果你想在一个文本块中找到所有重复的单词,可以使用一个正则表达式。如果你想替......
  • mysql索引
       2.1索引概述2.1.1介绍索引(index)是帮助MySQL高效获取数据的数据结构(有序)。在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法,这种数据结构就是索引。在无索引情况下,就需要......
  • RockyLinux安装MySQL
    本文介绍RockyLinux使用dnf在线安装MySQL并修改密码设置远程登陆。本博客使用RetHat系的新版本系统,如使用Debian系的系统如Ubuntu,只需使用apt安装,其余部分类似。1、使用如下命令安装MySQLsudodnfinstallmysql-server2、安装完成后可以使用systemctl工具对MySQL服务进行控......
  • MySQL 5.7 Reference Manual Optimization Overview(翻译)
    使用Kimi翻译文档地址:https://dev.mysql.com/doc/refman/5.7/en/optimize-overview.html目录8.1OptimizationOverview在数据库层面进行优化在硬件层面进行优化平衡可移植性和性能8.1OptimizationOverview数据库性能取决于数据库层面的多个因素,例如表、查询和配置设置。这......
  • MySQL 5.7 Reference Manual Optimizing SQL Statements(翻译)
    使用Kimi翻译文档地址:https://dev.mysql.com/doc/refman/5.7/en/optimize-overview.html目录8.2OptimizationOverview8.2.1优化SELECT语句8.2.2优化子查询、派生表和视图引用8.2.3优化INFORMATION_SCHEMA查询8.2.4优化数据变更语句8.2.5优化数据库权限8.2.6其他优化技巧......
  • SQL Injection | MySQL 手工注入全流程
    0x01:MySQL手工注入——理论篇手工注入MySQL数据库,一般分为以下五个阶段,如下图所示:第一阶段-判断注入点:在本阶段中,我们需要判断注入点的数据类型(数字型、字符型、搜索型、XX型)与后端查询方式,并使用对应的SQL语句进行测试,判断出目标是否存在注入点。第二阶段-......