MySql中ON DUPLICATE KEY UPDATE用法解析

本文介绍了一种在MySQL中高效处理数据插入与更新的方法——使用ON DUPLICATE KEY UPDATE语句。这种方法可以避免繁琐的查询和条件判断,提高数据处理效率。

在项目中常见的一种应用情景是,每做完一件事情都要更新一下统计表,就要根据主键去统计表里面去查询是否已经有这样的一条记录,如果有就更新,如果没有就插入一条记录。常见的做法是写三条sql语句:

select * from player_count where player_id = 1;//查询统计表中是否有记录

insert into player_count(player_id,count) value(1,1);//没有记录就执行insert 操作

update player_count set count = count+1 where player_id = 1;//有记录就执行update操作


这种写法比较麻烦,性能也不高,可用on duplicate key update去做

insert into player_count(player_id,count) value(1,1) on duplicate key update count=count+1;

这样每次不管插入还是更新都调用这个语句就能达到我们要的效果,省了不少的判断。


如果在INSERT语句末尾指定了ON DUPLICATE KEY UPDATE,并且插入行后会导致在一个UNIQUE索引或PRIMARY KEY中出现重复值,则在出现重复值的行执行UPDATE;如果不会导致唯一值列重复的问题,则插入新行。

例如,如果列 a 为 主键 或 拥有UNIQUE索引,并且包含值1,则以下两个语句具有相同的效果:

INSERT INTO TABLE (a,c) VALUES (1,3) ON DUPLICATE KEY UPDATE c=c+1;
UPDATE TABLE SET c=c+1 WHERE a=1;

如果行作为新记录被插入,则受影响行的值显示1;如果原有的记录被更新,则受影响行的值显示2。
如果INSERT多行记录(假设 a 为主键或 a 是一个 UNIQUE索引列):

INSERT INTO TABLE (a,c) VALUES (1,3),(1,7) ON DUPLICATE KEY UPDATE c=c+1;

执行后, c 的值会变为 4 (第二条与第一条重复, c 在原值上+1).

INSERT INTO TABLE (a,c) VALUES (1,3),(1,7) ON DUPLICATE KEY UPDATE c=VALUES(c);

执行后, c 的值会变为 7 (第二条与第一条重复, c 在直接取重复的值7).
注意:ON DUPLICATE KEY UPDATE只是MySQL的特有语法,并不是SQL标准语法!
这个语法和适合用在需要 判断记录是否存在,不存在则插入存在则更新的场景.

### SQL Server 中实现类似 MySQL `ON DUPLICATE KEY UPDATE` 的方法 在 SQL Server 中,可以使用 `MERGE` 语句来实现类似于 MySQL 的 `ON DUPLICATE KEY UPDATE` 功能。`MERGE` 语句允许在一个原子操作中同时执行插入、更新或删除操作,具体取决于目标表和源数据之间的匹配情况。 以下是一个基于 SQL Server 的 `MERGE` 语句示例,展示如何实现类似功能: ```sql -- 创建一个示例表 CREATE TABLE TargetTable ( ID INT PRIMARY KEY, Name NVARCHAR(50), UpdateTime DATETIME ); -- 插入初始数据 INSERT INTO TargetTable (ID, Name, UpdateTime) VALUES (1, '张三', GETDATE()); -- 使用 MERGE 实现类似 ON DUPLICATE KEY UPDATE 的功能 MERGE INTO TargetTable AS Target USING (SELECT 1 AS ID, '李四' AS Name, GETDATE() AS UpdateTime) AS Source ON Target.ID = Source.ID WHEN MATCHED THEN UPDATE SET Target.Name = Source.Name, Target.UpdateTime = Source.UpdateTime WHEN NOT MATCHED THEN INSERT (ID, Name, UpdateTime) VALUES (Source.ID, Source.Name, Source.UpdateTime); ``` #### 解释 - `MERGE INTO TargetTable AS Target` 指定目标表为 `TargetTable`。 - `USING (...) AS Source` 定义源数据集,这里是一个内联查询结果。 - `ON Target.ID = Source.ID` 定义匹配条件,类似于 MySQL 中的主键或唯一键判断[^4]。 - `WHEN MATCHED THEN UPDATE ...` 表示当目标表中存在匹配记录时,执行更新操作。 - `WHEN NOT MATCHED THEN INSERT ...` 表示当目标表中不存在匹配记录时,执行插入操作。 这种语法与 MySQL 的 `ON DUPLICATE KEY UPDATE` 功能非常相似,但更灵活,支持更多复杂的场景[^5]。 --- ### 示例代码扩展 如果需要更新多个字段或处理复杂逻辑,可以扩展 `MERGE` 语句。例如: ```sql MERGE INTO TargetTable AS Target USING (SELECT 2 AS ID, '王五' AS Name, GETDATE() AS UpdateTime) AS Source ON Target.ID = Source.ID WHEN MATCHED THEN UPDATE SET Target.Name = CASE WHEN Target.Name <> Source.Name THEN Source.Name ELSE Target.Name END, Target.UpdateTime = GETDATE() WHEN NOT MATCHED THEN INSERT (ID, Name, UpdateTime) VALUES (Source.ID, Source.Name, Source.UpdateTime); ``` 上述代码中,`CASE` 语句用于确保仅在必要时更新某些字段[^3]。 --- ### 注意事项 - 在 SQL Server 中,`MERGE` 语句要求目标表和源数据集之间有明确的匹配条件。 - 如果需要根据多个唯一键进行判断,可以在 `ON` 子句中添加更多条件。 - 确保目标表的主键或唯一约束定义正确,否则可能导致意外行为[^4]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值