当前位置: 代码网 > it编程>数据库>Mysql > MySql两表关联更新update示例SQL语句(用一个表更新另一个表)

MySql两表关联更新update示例SQL语句(用一个表更新另一个表)

2025年06月27日 Mysql 我要评论
前言本文介绍了如何通过sql语句实现两个表之间的关联更新,具体涉及city表和people表。city表包含城市代码和名称,people表包含人员信息及其所在城市的代码和名称。需求是根据city表更新

前言

本文介绍了如何通过sql语句实现两个表之间的关联更新,具体涉及city表和people表。city表包含城市代码和名称,people表包含人员信息及其所在城市的代码和名称。需求是根据city表更新people表中的城市名称。文章提供了两种更新方式:一种是在未匹配到关联数据时保留原有数据,另一种是未匹配时清空原有数据。此外,还介绍了如何通过触发器记录更新操作,并创建了审计表people_audit来存储更新前后的数据。文章通过示例sql语句展示了不同情况下的更新效果,并总结了更新时的注意事项。

两表关联更新update (用一个表更新另一个表)

表及数据

  • 建表及数据sql

    set names utf8mb4;
    set foreign_key_checks = 0;
    
    -- ----------------------------
    -- table structure for city
    -- ----------------------------
    drop table if exists `city`;
    create table `city`  (
      `code` varchar(3) character set utf8mb4 collate utf8mb4_general_ci null default null,
      `name` varchar(10) character set utf8mb4 collate utf8mb4_general_ci null default null
    ) engine = innodb character set = utf8mb4 collate = utf8mb4_general_ci row_format = dynamic;
    
    -- ----------------------------
    -- records of city
    -- ----------------------------
    insert into `city` values ('001', '北京');
    insert into `city` values ('002', '上海');
    insert into `city` values ('003', '深圳');
    insert into `city` values ('004', '南京');
    insert into `city` values ('005', '广州');
    insert into `city` values ('006', '成都');
    insert into `city` values ('007', '重庆');
    
    set foreign_key_checks = 1;
     
    set names utf8mb4;
    set foreign_key_checks = 0;
    
    -- ----------------------------
    -- table structure for people
    -- ----------------------------
    drop table if exists `people`;
    create table `people`  (
      `pp_id` int null default null,
      `pp_name` varchar(10) character set utf8mb4 collate utf8mb4_general_ci null default null,
      `city_code` varchar(3) character set utf8mb4 collate utf8mb4_general_ci null default null,
      `city_name` varchar(10) character set utf8mb4 collate utf8mb4_general_ci null default null
    ) engine = innodb character set = utf8mb4 collate = utf8mb4_general_ci row_format = dynamic;
    
    -- ----------------------------
    -- records of people
    -- ----------------------------
    insert into `people` values (1, 'john', '001', '北京');
    insert into `people` values (2, 'timo', '002', '');
    insert into `people` values (3, '张三', '003', '合肥');
    insert into `people` values (4, '李四', '008', '');
    insert into `people` values (5, '王二麻', '009', '黑龙江');
    
    set foreign_key_checks = 1;
    

city表

codename
1北京
2上海
3深圳
4南京
5广州
6成都
7重庆

people表

pp_idpp_namecity_codecity_name
1john1北京
2timo2
3张三3合肥
4李四8
5王二麻9黑龙江

需求

根据city表的code和name,更新people的city_name。

创建触发器

为了方便查看更新了那些行数据,为people表创建触发器

先创建记录people更新记录的审计表

create table `people_audit` (
  `id` int default null,
  `old_value` varchar(10) collate utf8mb4_general_ci default null,
  `new_value` varchar(10) collate utf8mb4_general_ci default null,
  `updated_at` datetime default null
) engine=innodb default charset=utf8mb4 collate=utf8mb4_general_ci;

创建每一行更新后触发器

create trigger before_update_people
before update on people
for each row
begin
  insert into people_audit(id, old_value, new_value, updated_at)
  values(old.pp_id, old.city_name, new.city_name, now());
end;

关联无匹配,保持原数据

update people p , city c
set p.city_name = c.name 
where p.city_code = c.code 

正常情况:city表的code唯一

执行上面sql,输出:

idold_valuenew_valueupdated_at
1北京北京2024-5-13 10:19
2上海2024-5-13 10:19
3合肥深圳2024-5-13 10:19

数据修改了三行,结论

  • 代码对应的城市更新,对应错误的更正
  • city表中没有的城市,在people表里保持原数据,不会被清空

异常情况:city表的code不唯一

插入一个重复code的数据

insert into city values('003','合肥');

恢复people表到初始数据,再次执行上面的更新sql,可以发现与上面返回值一致。

推论:只取先匹配的一个值替换

关联无匹配,清空原数据

update people 
set city_name = (
                select min(name) -- 重复时匹配其中一个
                from city
                where code = people.city_code)

或者

update people p 
left join city c on p.city_code=c.`code`
set p.city_name = c.`name`

正常情况:city表的code唯一

idold_valuenew_valueupdated_at
1北京北京2024-5-13 10:26
2上海2024-5-13 10:26
3合肥深圳2024-5-13 10:26
42024-5-13 10:26
5黑龙江2024-5-13 10:26

数据修改了5行,结论

  • 代码对应的城市更新,对应错误的更正
  • city表中没有的城市,在people表里全被更新为null

异常情况:city表的code不唯一

不会报错,会选匹配其中一个更新。

结论

更新时未匹配到关联数据

未匹配,保留原有数据

update people p , city c  -- 两张表
set p.city_name = c.name   -- 更新值
where p.city_code = c.code -- 条件

未匹配,清空原有数据

update people 
set city_name = (
                select min(name) -- 重复时匹配其中一个
                from city
                where code = people.city_code)  

或者

update people p -- 要更新的表
left join city c on p.city_code=c.`code` -- 关联取数据的表
set p.city_name = c.`name` --更新表字段

总结 

到此这篇关于mysql两表关联更新update示例sql语句的文章就介绍到这了,更多相关mysql两表关联更新update内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

  • MySQL之InnoDB存储引擎中的索引用法及说明

    MySQL之InnoDB存储引擎中的索引用法及说明

    1、背景innodb存储引擎的基本存储单位是页,索引也是存储在页上的,b+树中非叶子节点的页也是数据页,和我们插入数据的区别是存放的行记录叫目录项记录,我们插入... [阅读全文]
  • mysql中的服务器架构详解

    mysql中的服务器架构详解

    1、背景简单理解一下mysql的服务器架构。2、mysql服务器架构解释mysql的架构图如下:主要分为三部分:客户端、服务端、存储引擎。接下来我们来解释一下各... [阅读全文]
  • MySQL之InnoDB中的锁用法

    MySQL之InnoDB中的锁用法

    1、背景为了满足数据库对数据的一致性、事务隔离性、高并发性能需求,就有了锁机制,innodb的锁机制是实现事务隔离性和并发控制的核心组件,接下来就来讲一下锁机制... [阅读全文]
  • MySQL之InnoDB中的MVCC用法

    MySQL之InnoDB中的MVCC用法

    1、背景mvcc叫做多版本并发控制,通过维护数据的多个历史版本实现读写分离:读操作访问快照版本,无需加锁,避免阻塞写操作;写操作创建新版本,不影响其它事务的读操... [阅读全文]
  • MySQL之undo日志页结构详解

    1、背景之前讲过undo日志类型,本篇文章再来具体讲解一下undo日志页结构。2、undo日志页结构【1】fil_page_undo_log页innodb中最基本的存储单位是页,u…

    2025年06月26日 数据库
  • MySQL中的undo日志类型使用

    MySQL中的undo日志类型使用

    1、背景事务的回滚机制是通过undo日志来实现的,我们只需要对insrt、delete、update操作记录回滚日志,select不需要记录回滚日志,这三种操作... [阅读全文]

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com