SQL按UniqueKey分组求和后更新原表删除重复数据方法
问题背景
现有数据表Table1,原始数据如下:
| UniqueKey | Text A | Text B | Value 1 | Value 2 |
|---|---|---|---|---|
| Key1 | ABC | ABC | 2 | 3 |
| Key2 | DEF | GHI | 3 | 4 |
| Key3 | STE | GGE | 5 | 5 |
| Key2 | DEF | GHI | 3 | 4 |
| Key2 | DEF | GHI | 5 | 7 |
| Key1 | ABC | ABC | 3 | 7 |
需要以UniqueKey为分组键,对同组的Value 1、Value 2求和,最终每个UniqueKey仅保留1条记录,目标结果如下:
| UniqueKey | Text A | Text B | Value 1 | Value 2 |
|---|---|---|---|---|
| Key1 | ABC | ABC | 5 | 10 |
| Key2 | DEF | GHI | 11 | 15 |
| Key3 | STE | GGE | 5 | 5 |
目前已经写出基础的分组聚合查询,但不知道如何把聚合结果更新回原表,同时删除重复冗余行。
SELECT UniqueKey, SUM(Value1) Value1, SUM(Value2) Value2 FROM Table1 GROUP BY UniqueKey
实现方案
方案1:临时表中转(全数据库兼容,最稳妥)
这个方案没有语法兼容问题,所有支持SQL的数据库都能跑,操作逻辑简单,不容易出错:
- 第一步:创建临时表存储聚合完成的正确数据,同组下
Text A、Text B值完全一致,用MAX()/MIN()取组内值即可:
-- 注意:如果字段名带空格,请根据你用的数据库加对应标识符,比如MySQL用`Text A`,SQL Server用[Text A] CREATE TEMPORARY TABLE temp_t1 AS SELECT UniqueKey, MAX(`Text A`) AS `Text A`, MAX(`Text B`) AS `Text B`, SUM(`Value 1`) AS `Value 1`, SUM(`Value 2`) AS `Value 2` FROM Table1 GROUP BY UniqueKey;
- 第二步:清空原表所有数据:
TRUNCATE TABLE Table1;
- 第三步:把临时表的正确数据插回原表,最后删除临时表即可:
INSERT INTO Table1 (UniqueKey, `Text A`, `Text B`, `Value 1`, `Value 2`) SELECT UniqueKey, `Text A`, `Text B`, `Value 1`, `Value 2` FROM temp_t1; DROP TEMPORARY TABLE temp_t1;
方案2:MERGE语句单表操作(适合支持MERGE语法的数据库)
如果你的数据库版本支持MERGE语法(Oracle、SQL Server、PostgreSQL 15+、MySQL 8.0.19+均支持),可以直接单语句完成更新+删重,不需要建临时表:
MERGE INTO Table1 t1 USING ( SELECT UniqueKey, MAX(`Text A`) AS `Text A`, MAX(`Text B`) AS `Text B`, SUM(`Value 1`) AS sum_v1, SUM(`Value 2`) AS sum_v2, ROW_NUMBER() OVER (PARTITION BY UniqueKey ORDER BY UniqueKey) AS rn FROM Table1 GROUP BY UniqueKey ) t2 ON t1.UniqueKey = t2.UniqueKey WHEN MATCHED AND rn = 1 THEN UPDATE SET t1.`Value 1` = t2.sum_v1, t1.`Value 2` = t2.sum_v2 WHEN MATCHED AND rn > 1 THEN DELETE;
操作前务必备份原表数据,避免误操作导致数据丢失。
内容的提问来源于stack exchange,提问作者tommy74
相关产品推荐
相关产品推荐

