摘要:在MySQL中,我们在执行update或者insert语句时,可以借助select语句更新一个字段,使其值更新为该字段的最大值加1。

  在《MySQL中自增长序列(@i:=@i+1)的用处及用法》中,介绍了如何在select语句中生成递增序列,《MySQL 把查询结果更新或者插入到新表》介绍了把查询到的多条记录复制到另一张表中,均没有介绍如何更新数据库字段的值为当前最大值加指定步长。所以在本文中,楼兰胡杨将带着大家了解如何更新某个字段的值为当前最大值加指定步长1,步长也可以是其它满足诉求的值。

创建测试表

  使用以下 MySQL 语句创建测试表test并写入三条测试数据:

CREATE TABLE test (
`id` bigint(20) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT '主键ID',
incr_id INT NOT NULL COMMENT '递增序列',
creator varchar(30) NOT NULL COMMENT '创建者'
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '测试表'; INSERT INTO test(incr_id,creator) VALUES (FLOOR(1 + RAND() * 100),"张三");
INSERT INTO test(incr_id,creator) VALUES (FLOOR(1 + RAND() * 100),"张三丰");
INSERT INTO test(incr_id,creator) VALUES (FLOOR(1 + RAND() * 100),"楼兰胡杨");

  表中incr_id用于演示如何更新它的值为其当前最大值加1。当然,令其如主键ID一样支持AUTO_INCREMENT时,可以实现自增长,实现方案非常简单,本文不再赘述。这里主要讲述如何通过update select和insert select实现字段值递增的策略。

update select实现字段递增赋值

  首先使用聚合函数max来计算最大值,然后将其加1。以下SQL将返回test表中incr_id字段的最大值并且加1:

SELECT MAX(incr_id)+1 FROM test;

  运行此命令后,将返回一个包含最大值加1的单独的列。接下来,楼兰胡杨将此用作update语句的源值,以下实现方案基于嵌套子查询完成:

UPDATE test
SET incr_id = (
SELECT max_incr FROM (
SELECT MAX(incr_id) + 1 AS max_incr FROM test
) AS tmp
)
WHERE id = 3;

  在这个更新DML中,我们在子查询语句中使用聚合函数max计算字段最大值,然后对其最大值加1。与前面的例子一样,WHERE子句用于指定要更新的记录。这个方案因为耗内存、效率低而不适用于批量更新场景,但变量模拟自增方案适用于批量更新或复杂逻辑控制,实现脚本如下:

-- 自定义变量
SET @max_incr = (SELECT MAX(incr_id) + 1 FROM test);
-- 使用变量更新字段
UPDATE test SET incr_id = @max_incr WHERE id = 3;

insert select实现字段递增赋值

  在insert操作中实现字段递增赋值时,也是首先使用聚合函数max来计算最大值,然后将其加1。先介绍一下insert select语法糖:

INSERT INTO target_table (column1, column2, ...)
SELECT value1, value2, ...
FROM source_table_a a JOIN source_table_b b ON a.id = b.a_id
WHERE condition_clause;
  • target_table:用于插入数据的目标表。
  • source_table_a 和 source_table_b:源表,从中选择数据用于插入目标表。可以从多个表中选择数据并插入到目标表中,可以一个表。
  • value1, value2, …:被插入到目标表的值,既可以是从源表中选择的列,也可以是返回常量的表达式,更可以是一个常量。在编写SELECT语句的时候,可以使用MySQL支持的全部语法。

  下面使用上述语法糖新增一条记录,并且令incr_id字段的新值为其最大值加1:

INSERT INTO test ( `incr_id`, `creator`)
SELECT IFNULL(max(incr_id), 0) + 1, '递增序列' FROM test;

  IFNULL是专门处理 NULL 值的。若目标表的某些列不允许为 NULL,而假设 SELECT 查询返回 NULL 值,会导致数据插入操作失败。这种书写格式与如下常见VALUES写法区别很大:

INSERT INTO test(incr_id) VALUES (FLOOR(1 + RAND() * 100),"普通insert操作");

小结

  本篇文章的内容基本上就是这些,我们来复盘一下。在本文中,我们提供了一些使用MySQL select语句更新字段的示例,这些DML可以使用聚合函数或者嵌套子查询来计算要设置的新值。各位老铁无论选择哪种方式,都需要确保更新操作仅更新需要更新的记录,否则您可能会无意中、错误地更改了整张表的记录。楼兰胡杨还提到,如果您的表包含大量记录,使用SELECT子查询操作可能会比较慢,而借助自定义变量计算最大值的方案可能更轻快。

  欢迎点赞阅读,一同学习交流;若有疑问,请在文章下方留下你的神评妙论!以促使博文高质量。

MySQL 更新字段的值为当前最大值加1的更多相关文章

  1. mysql更新字段值提示You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column To disable safe mode

    1 引言 当更新字段缺少where语句时,mysql会提示一下错误代码: Error Code: 1175. You are using safe update mode and you tried ...

  2. Mysql 修改字段默认值

    环境:MySQL 5.7.13 问题描述:建表的时候,users_info表的role_id字段没有默认值,后期发现注册的时候,需要提供给用户一个默认角色,也就是给role_id字段一个默认值. 当前 ...

  3. MySQL更新字段来自另一个表的count()值

    假设有文章post和评论comment两个表,文章表记录有评论的数量,但是这个值我们要一次更新. 如下,现在post表的comment_count都是0,我们的目标是:执行一个SQL语句,让其把统计c ...

  4. MySQL 触发器-更新字段时,status列会加一

    需求:当更新列中的字段时,列中的status字段,就会+1 表结构 CREATE TABLE `test_1` ( `id` int(11) DEFAULT NULL, `name` varchar( ...

  5. mySql一个字段的值模糊匹配多表多列的查询

    1.dao层/** * 分页查询点卡集合信息 * @param tid 游戏类型编号 * @param gid 游戏编号 * @param searchInfo 包括(点卡名称,游戏名称,点卡面值,游 ...

  6. mysql更新字段内容

    update article set a_content = REPLACE(`a_content`,'www.abc.com','www.bcd.com')

  7. mysql 查找多个值并且取最大值一个和分组

    SELECT eco_truename, eco_uid, max(checkup_time) AS time FROM es_checkup_order WHERE checkup_time GRO ...

  8. mysql更新某个字符串字段的部分内容

    如果现在需要Mysql更新字段重部分数据,而不是全部数据,应该采用何种方法呢?下面介绍了两种情况下Mysql更新字段中部分数据的方法,供您参考. Mysql更新字段中部分数据第一种情况: update ...

  9. Mysql多字段模糊查询

    MySQL同一字段多值模糊查询 一. 同一字段多值模糊查询,使用多个or进行链接,效率不高,但没有更好的解决方案.(有看到CHARINDEX 关键字,可查询结果并不是模糊,举个栗子 例如SELECT ...

  10. mysql变成类型字段varchar值更新变长或变短底层文件存储原理

    为了搞清楚MySQL对于可变长度字段值修改时,如何高效操作数据文件的机制.之前一直模糊不清,网上也搜不到现成的答案.经过多方资料搜集整理.写出此文供大家一起参阅.由于涉及众多非常底层的知识,我假设读者 ...

随机推荐

  1. 腾讯出品!这款Markdown神器让你码字效率翻倍,双模式编辑太香了!

    嗨,大家好,我是小华同学,关注我们获得"最新.最全.最优质"开源项目和高效工作学习方法 由腾讯开源的CherryMarkdown编辑器,集思维导图式大纲写作与专业分屏模式于一身,支 ...

  2. 【BUG】Message = “无法加载一个或多个请求的类型。有关更多信息,请检索 LoaderExceptions 属性。“, StackTrace = “ 在 System.Reflection.

    环境: Visual Studio 2019 C#项目遇到这种情况时,是因为有多个依赖出了问题(也可能是只有一个但被误报成多个),此时点开"查看详细信息",可以快速监视Except ...

  3. Flex布局-margin 妙用技巧

    在 flex 布局 中, 通过对子项设置 margin-auto; 的方式去吃掉剩余空间, 这种小技巧在很多时候能极大简化我们的布局哦. 单元素水平垂直居中 如果父容器是 flex, 要实现元素水平垂 ...

  4. Python基础 - 多线程(下)

    上篇对多线程有一个初步的认识, 常用的要点, 也是对照这 多进程 来试验的. 目的呢, 还是再不断地提醒自己能通俗理解进程和线程的"关系", OS -> 多进程 -> ...

  5. 开源我的一款自用AI阅读器,引流Web前端、Rust、Tauri、AI应用开发

    前沿 - 为什么要做这个开源软件 作为一个典型的前端开发者,去年在为公司调研Rust前端工具链.LLM应用开发技术体系的时候,对这类技术领域产生了浓厚的兴趣,也是出于早期曾经是一名Android移动应 ...

  6. JS的哪些新特性,你都用过么?

    @charset "UTF-8"; .markdown-body { line-height: 1.75; font-weight: 400; font-size: 15px; o ...

  7. 【SQL周周练】:利用行车轨迹分析犯罪分子作案地点

    大家好,我是"蒋点数分",多年以来一直从事数据分析工作.从今天开始,与大家持续分享关于数据分析的学习内容. 本文是第 7 篇,也是[SQL 周周练]系列的第 6 篇.该系列是挑选或 ...

  8. ListBox横向排布Item

    <Window x:Class="TwoColumnListBox.MainWindow" xmlns="http://schemas.microsoft.com/ ...

  9. B1009 说反话

    给定一句英语,要求你编写程序,将句中所有单词的顺序颠倒输出. 输入格式: 测试输入包含一个测试用例,在一行内给出总长度不超过 80 的字符串.字符串由若干单词和若干空格组成,其中单词是由英文字母(大小 ...

  10. MySQL Explain查看执行计划详解

    目录 前言 EXPLAIN 中的列 id 和select_type table type possible_keys key 和 key_len ref 和 rows Extra 小结 Referen ...