新手求助:基于CSV与目标表的条件更新/插入SQL实现
实现CSV数据与目标表的UPSERT(更新/插入)方案
嘿,作为SQL新手遇到这种「存在就更新,不存在就插入」的需求很正常,咱们一步步来搞定它:
第一步:把CSV数据导入临时表
直接操作CSV文件不太方便,咱们先把CSV里的内容导入一个临时表(用完可以删掉的那种),不同数据库的导入方式略有不同:
如果你用的是SQL Server
-- 创建临时表,结构要和CSV对应(这里只需要Value1和Value2,其他列如果不需要可以忽略) CREATE TABLE #TempCSV ( Value1 VARCHAR(255), -- 这里的类型要和目标表的Value1一致,比如如果是数字就用INT Value2 VARCHAR(255) -- 同理,类型匹配目标表的Value2 ); -- 导入CSV数据,注意替换文件路径和分隔符(比如CSV是逗号分隔就用FIELDTERMINATOR = ',') BULK INSERT #TempCSV FROM 'C:\你的CSV文件路径\data.csv' WITH ( FIELDTERMINATOR = ',', ROWTERMINATOR = '\n', FIRSTROW = 2 -- 如果CSV第一行是表头,就从第二行开始导入 );
如果你用的是MySQL
-- 创建临时表 CREATE TEMPORARY TABLE TempCSV ( Value1 VARCHAR(255), Value2 VARCHAR(255) ); -- 导入CSV,注意替换文件路径和字符集,LOCAL选项需要确保数据库配置允许 LOAD DATA LOCAL INFILE '/你的CSV文件路径/data.csv' INTO TABLE TempCSV FIELDS TERMINATED BY ',' ENCLOSED BY '"' -- 如果CSV字段用引号包裹就加上这个 LINES TERMINATED BY '\n' IGNORE 1 ROWS; -- 跳过表头行
如果你用的是PostgreSQL
-- 创建临时表 CREATE TEMPORARY TABLE TempCSV ( Value1 VARCHAR(255), Value2 VARCHAR(255) ); -- 导入CSV,psql命令行执行的话用这个,或者用pgAdmin的导入工具 COPY TempCSV FROM '/你的CSV文件路径/data.csv' WITH ( FORMAT csv, HEADER true, -- 有表头就加这个 DELIMITER ',' );
重要提醒:临时表的字段类型一定要和目标表的
Value1、Value2完全匹配,不然会出现数据类型错误!另外,目标表的Value1列必须设置唯一约束(比如主键或者UNIQUE索引),这样数据库才能判断哪些行是重复的。
第二步:执行UPSERT操作
现在临时表有数据了,咱们就可以和目标表做匹配,实现「存在更新,不存在插入」:
SQL Server 用MERGE语句
MERGE INTO 目标表 AS Target USING #TempCSV AS Source ON Target.Value1 = Source.Value1 -- 匹配条件:Value1相等 WHEN MATCHED THEN UPDATE SET Target.Value2 = Source.Value2 -- 匹配到就更新Value2 WHEN NOT MATCHED THEN INSERT (Value1, Value2) -- 没匹配到就插入新行,这里如果目标表有其他必填列也要加上 VALUES (Source.Value1, Source.Value2);
MySQL 用INSERT ... ON DUPLICATE KEY UPDATE
INSERT INTO 目标表 (Value1, Value2) SELECT Value1, Value2 FROM TempCSV ON DUPLICATE KEY UPDATE Value2 = VALUES(Value2); -- 当Value1重复时,更新Value2为CSV里的值
PostgreSQL 用INSERT ... ON CONFLICT
INSERT INTO 目标表 (Value1, Value2) SELECT Value1, Value2 FROM TempCSV ON CONFLICT (Value1) DO UPDATE -- 当Value1冲突(重复)时 SET Value2 = EXCLUDED.Value2; -- EXCLUDED代表要插入的那条数据
第三步:清理临时表(可选)
操作完成后,临时表可以删掉释放资源:
- SQL Server:
DROP TABLE #TempCSV; - MySQL/PostgreSQL:临时表会在会话结束后自动删除,也可以手动
DROP TABLE TempCSV;
这样一套操作下来,就能完美实现你要的需求啦!
内容的提问来源于stack exchange,提问作者Metaldream
相关产品推荐
相关产品推荐

