前言
本文介绍了如何通过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表
code | name |
---|---|
1 | 北京 |
2 | 上海 |
3 | 深圳 |
4 | 南京 |
5 | 广州 |
6 | 成都 |
7 | 重庆 |
people表
pp_id | pp_name | city_code | city_name |
---|---|---|---|
1 | john | 1 | 北京 |
2 | timo | 2 | |
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,输出:
id | old_value | new_value | updated_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唯一
id | old_value | new_value | updated_at |
---|---|---|---|
1 | 北京 | 北京 | 2024-5-13 10:26 |
2 | 上海 | 2024-5-13 10:26 | |
3 | 合肥 | 深圳 | 2024-5-13 10:26 |
4 | 2024-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内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论