SQL 删除值相同的多余行?
SQL to delete surplus rows where values are the same?
我有一个 table 看起来像这样:
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 使用此代码删除我需要的数据:
select *
from (
select *, row_number() over(partition by week, value1, value2 order by week, value1, value2) as row
from mytable
)
where row >1
有谁知道如何最好地从 table 中实际删除这些行?
我使用的是 db2 数据库,如果这有助于缩小do/don不起作用的功能范围。
不幸的是,在许多数据库中删除精确的重复项很棘手,我认为在 DB2 中也是如此。一种选择是添加一个新列来唯一标识每一行。另一种是重新创建 table:
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
);
您想删除存在具有较低 value3 的同级的行(以便仅保留具有最低 value3 的行)。
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
);
尝试以下操作。它至少适用于 LUW 的 Db2。
DELETE FROM
(
SELECT ROW_NUMBER () OVER (PARTITION BY WEEK, VALUE1, VALUE2 ORDER BY VALUE3) RN_
FROM MYTABLE
)
WHERE RN_ <> 1;
解决编码问题的方法有很多种。我使用 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.
这将清理 table 但更好的解决方案是按照之前的建议在插入时防止重复。
我有一个 table 看起来像这样:
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 使用此代码删除我需要的数据:
select *
from (
select *, row_number() over(partition by week, value1, value2 order by week, value1, value2) as row
from mytable
)
where row >1
有谁知道如何最好地从 table 中实际删除这些行?
我使用的是 db2 数据库,如果这有助于缩小do/don不起作用的功能范围。
不幸的是,在许多数据库中删除精确的重复项很棘手,我认为在 DB2 中也是如此。一种选择是添加一个新列来唯一标识每一行。另一种是重新创建 table:
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
);
您想删除存在具有较低 value3 的同级的行(以便仅保留具有最低 value3 的行)。
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
);
尝试以下操作。它至少适用于 LUW 的 Db2。
DELETE FROM
(
SELECT ROW_NUMBER () OVER (PARTITION BY WEEK, VALUE1, VALUE2 ORDER BY VALUE3) RN_
FROM MYTABLE
)
WHERE RN_ <> 1;
解决编码问题的方法有很多种。我使用 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.
这将清理 table 但更好的解决方案是按照之前的建议在插入时防止重复。