SQL删除值相同的多余行?
Posted
技术标签:
【中文标题】SQL删除值相同的多余行?【英文标题】:SQL to delete surplus rows where values are the same? 【发布时间】:2021-09-24 10:14:52 【问题描述】:我有一张如下所示的表格:
Week | Value1 | Value2 | Value3
-----|--------|--------|-------
1 | A | A | 5
1 | A | B | 10
1 | B | B | 15
2 | A | A | 10
2 | A | B | 15
2 | B | B | 20
2 | A | A | 10
2 | A | B | 15
2 | B | B | 25
我想删除 Week、Value1 和 Value2 匹配的多余行,但保留原始行不变。所以想要的结果应该是这样的:
Week | Value1 | Value2 | Value3
-----|--------|--------|-------
1 | A | A | 5
1 | A | B | 10
1 | B | B | 15
2 | A | A | 10
2 | A | B | 15
2 | B | B | 20
我可以使用此代码选择我需要删除的数据:
select *
from (
select *, row_number() over(partition by week, value1, value2 order by week, value1, value2) as row
from mytable
)
where row >1
请问有谁知道如何最好地从表中实际删除这些行?
我使用的是 db2 数据库,如果这有助于缩小哪些功能起作用/不起作用。
【问题讨论】:
当你谈到'剩余'时,你如何生成源表?它是如何填充的?根据这一点,解决方案可能会有所不同 你如何分辨哪一行要保留,哪一行要取消?例如,第 2 周的 B/B 行有两行,您保留 value3 = 20 的一行,关闭 value3 = 25 的一行。您如何做出该决定? @Christophe 每周运行一个自动作业,以将该周的数据附加到表中。这项工作还从去年同期的同周数据中提取了同比数据,但由于它现在已经活跃了一年多,它开始提取已经在表格中的周数(现在已经纠正)。跨度> @ThorstenKettner 如果行的 value3 数字不同,则应保留值较低的行。 所以我认为应该在自动化作业中进行更改以确保唯一性,之后管理会更加复杂 【参考方案1】:不幸的是,在许多数据库中删除完全重复的内容很棘手,我认为在 DB2 中也是如此。一种选择是添加一个唯一标识每一行的新列。另一种是重新创建表:
create temporary table temp_mytable as
select distinct week, value1, value2
from mytable;
truncate mytable;
insert into mytable (week, value1, value2)
select week, value1, value2
from temp_mytable;
如果您对每一行都有一个唯一的 id,您只需使用:
delete from mytable
where id <> (select min(t2.id)
from mytable t2
where t2.week = t.week and t2.value1 = t.value1 and t2.value2 = t.value2
);
【讨论】:
谢谢!我通过使用 mytable 中的数据创建一个临时表以及一个用于标记受影响行的列(使用我原始帖子中的 row_number 列)对其进行了一些修改,然后截断了 mytable 并将其添加到标记所在的临时表中的数据中>1.【参考方案2】:您要删除存在具有较低值3 的兄弟的行(以便只保留具有最低值3 的行)。
delete from mytable
where exists
(
select null
from mytable better_row
where better_row.week = mytable.week
and better_row.value1 = mytable.value1
and better_row.value2 = mytable.value2
and better_row.value3 < mytable.value3
);
【讨论】:
【参考方案3】:试试下面的。它至少适用于 Db2 for LUW。
DELETE FROM
(
SELECT ROW_NUMBER () OVER (PARTITION BY WEEK, VALUE1, VALUE2 ORDER BY VALUE3) RN_
FROM MYTABLE
)
WHERE RN_ <> 1;
【讨论】:
【参考方案4】:有很多方法可以解决编码问题。我使用 iSeries DB2 和 SQL,不熟悉其他平台上的 DB2。由于您拥有正确识别要删除的行的 SQL 语句,因此另一个解决方案可能是...
1. Use an insert with the select statement that identifies the rows that are to be deleted and include RRN() in the select clause.
2. Then perform the delete statement based on RRN.
这会清理表,但更好的解决方案是按照之前的建议在插入时防止重复。
【讨论】:
以上是关于SQL删除值相同的多余行?的主要内容,如果未能解决你的问题,请参考以下文章