MySql兩表關(guān)聯(lián)更新update示例SQL語句(用一個表更新另一個表)
前言
本文介紹了如何通過SQL語句實現(xiàn)兩個表之間的關(guān)聯(lián)更新,具體涉及city表和people表。city表包含城市代碼和名稱,people表包含人員信息及其所在城市的代碼和名稱。需求是根據(jù)city表更新people表中的城市名稱。文章提供了兩種更新方式:一種是在未匹配到關(guān)聯(lián)數(shù)據(jù)時保留原有數(shù)據(jù),另一種是未匹配時清空原有數(shù)據(jù)。此外,還介紹了如何通過觸發(fā)器記錄更新操作,并創(chuàng)建了審計表people_audit來存儲更新前后的數(shù)據(jù)。文章通過示例SQL語句展示了不同情況下的更新效果,并總結(jié)了更新時的注意事項。
兩表關(guān)聯(lián)更新update (用一個表更新另一個表)
表及數(shù)據(jù)
建表及數(shù)據(jù)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 | 黑龍江 |
需求
根據(jù)city表的code和name,更新people的city_name。
創(chuàng)建觸發(fā)器
為了方便查看更新了那些行數(shù)據(jù),為people表創(chuàng)建觸發(fā)器
先創(chuàng)建記錄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;
創(chuàng)建每一行更新后觸發(fā)器
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;
關(guān)聯(lián)無匹配,保持原數(shù)據(jù)
UPDATE people p , city c SET p.city_name = c.name WHERE p.city_code = c.code
正常情況:city表的code唯一
執(zhí)行上面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 |
數(shù)據(jù)修改了三行,結(jié)論:
- 代碼對應(yīng)的城市更新,對應(yīng)錯誤的更正
- city表中沒有的城市,在people表里保持原數(shù)據(jù),不會被清空
異常情況:city表的code不唯一
插入一個重復(fù)code的數(shù)據(jù)
insert into city values('003','合肥');
恢復(fù)people表到初始數(shù)據(jù),再次執(zhí)行上面的更新sql,可以發(fā)現(xiàn)與上面返回值一致。
推論:只取先匹配的一個值替換
關(guān)聯(lián)無匹配,清空原數(shù)據(jù)
update people
set city_name = (
select min(name) -- 重復(fù)時匹配其中一個
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 |
數(shù)據(jù)修改了5行,結(jié)論:
- 代碼對應(yīng)的城市更新,對應(yīng)錯誤的更正
- city表中沒有的城市,在people表里全被更新為null
異常情況:city表的code不唯一
不會報錯,會選匹配其中一個更新。
結(jié)論
更新時未匹配到關(guān)聯(lián)數(shù)據(jù)
未匹配,保留原有數(shù)據(jù)
UPDATE people p , city c -- 兩張表 SET p.city_name = c.name -- 更新值 WHERE p.city_code = c.code -- 條件
未匹配,清空原有數(shù)據(jù)
update people
set city_name = (
select min(name) -- 重復(fù)時匹配其中一個
from city
where code = people.city_code)
或者
UPDATE people p -- 要更新的表 LEFT JOIN city c ON p.city_code=c.`code` -- 關(guān)聯(lián)取數(shù)據(jù)的表 SET p.city_name = c.`name` --更新表字段
總結(jié)
到此這篇關(guān)于MySql兩表關(guān)聯(lián)更新update示例SQL語句的文章就介紹到這了,更多相關(guān)MySql兩表關(guān)聯(lián)更新update內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
win10下mysql 5.7.17 zip壓縮包版安裝教程
這篇文章主要為大家詳細介紹了win10下mysql 5.7.17 zip壓縮包版安裝教程,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-03-03
MySQL如何根據(jù)不同條件聯(lián)查不同表的數(shù)據(jù)if/case
這篇文章主要介紹了MySQL如何根據(jù)不同條件聯(lián)查不同表的數(shù)據(jù)if/case問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-05-05

