You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

实现多列判断的SQL Upsert(存在更新/不存在插入)方案咨询

单条SQL实现下载记录的新增/更新(UPSERT)

要实现你说的「当月首次处理则新增,否则downloads加1」的逻辑,核心是用数据库的UPSERT(插入或更新)语法,前提是给summary表的fileId、month、year三个字段创建唯一联合索引——这是判断记录是否存在的核心依据。

下面分主流数据库给出具体实现:

1. MySQL / MariaDB

使用INSERT ... ON DUPLICATE KEY UPDATE语法:

INSERT INTO summary (fileId, month, year, downloads)
VALUES (?, ?, ?, 1)  -- ?为占位符,替换为实际的fileId、当月月份、当年年份
ON DUPLICATE KEY UPDATE downloads = downloads + 1;

原理:当插入的(fileId, month, year)组合触发唯一索引冲突时,执行更新操作将downloads加1;无冲突则直接插入新行,downloads初始值设为1。

2. PostgreSQL

使用INSERT ... ON CONFLICT ... DO UPDATE语法,需先创建唯一约束:

-- 先创建唯一约束
ALTER TABLE summary ADD CONSTRAINT unique_file_month_year UNIQUE (fileId, month, year);

-- 执行UPSERT
INSERT INTO summary (fileId, month, year, downloads)
VALUES ($1, $2, $3, 1)
ON CONFLICT (fileId, month, year) DO UPDATE 
SET downloads = summary.downloads + 1;

3. SQL Server

使用MERGE语句:

MERGE INTO summary AS target
USING (SELECT ? AS fileId, ? AS month, ? AS year) AS source
ON target.fileId = source.fileId AND target.month = source.month AND target.year = source.year
WHEN MATCHED THEN
    UPDATE SET downloads = target.downloads + 1
WHEN NOT MATCHED THEN
    INSERT (fileId, month, year, downloads)
    VALUES (source.fileId, source.month, source.year, 1);

关键注意事项

  • 必须确保(fileId, month, year)的唯一约束/索引存在,否则UPSERT逻辑会失效,甚至产生重复数据。
  • 针对每日大文件量的场景,可将多条记录合并为一个批量INSERT语句(比如MySQL支持VALUES (?, ?, ?, 1), (?, ?, ?, 1), ...),能大幅提升处理效率。
  • 高并发场景下,部分数据库支持在UPSERT时加锁(如PostgreSQL的ON CONFLICT ... DO UPDATE SKIP LOCKED),可避免竞态问题。

内容的提问来源于stack exchange,提问作者Murat Colyaran

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 16:45:36