我有一张这样的表:
ID, ItemsID
1 2
1 3
1 4
2 3
2 4
2 2
我想删除ID=2
之类的元组,因为在我的情况下2,3,4
与3,4,2
相同。
我该如何使用SQL?
答案 0 :(得分:1)
抱歉,我没有及时看到Oracle标签。但是,我将保留MySQL解决方案以供参考。 Apparently在某些Oracle版本中有类似GROUP_CONCAT()
的内容。
它可能不是最优雅的解决方案,但这可以完成这项工作:
DELETE FROM t WHERE ID IN (
SELECT ID
FROM (SELECT ID, GROUP_CONCAT(ItemsID ORDER BY ItemsID) AS tuple FROM t GROUP BY ID) AS tuples
WHERE EXISTS (
SELECT TRUE
FROM (SELECT ID, GROUP_CONCAT(ItemsID ORDER BY ItemsID) AS tuple FROM t GROUP BY ID) tuples2
WHERE tuples2.tuple = tuples.tuple
AND tuples2.ID < tuples.ID
)
)
您可能需要调整group_concat_max_len。
答案 1 :(得分:1)
另一种方法。 Oracle 10gR1或更高版本。在此示例中,我们为ItemsID
s 1,2,6提供了相同的ID
值集合,另一个用于3的值{另一个用于4和5.因此我们将删除{{1} } s 2,6和5,因为它们似乎是重复的,通过将特定ID
组的每组ItemsID
元素表示为嵌套表并使用ID
运算符来确定是否重复组中的元素是相同的:
multiset except
答案 2 :(得分:0)
这是我能想到的最好的,但不知怎的,我觉得必须有一个更简单的解决方案:
delete from items
where id in (
select id
from (
with counts as (
select id,
count(*) as cnt
from items
group by id
)
select c1.id, row_number() over (order by c1.id) as rn
from counts c1
join counts c2
on c1.id <> c2.id and c1.cnt = c2.cnt
and not exists (select i1.itemsid
from items i1
where i1.id = c1.id
minus
select i2.itemsid
from items i2
where i2.id = c2.id)
) t
where rn <> 1
);
它适用于任意数量的itemsid
值。
rn <> 1
结合窗口定义中的升序排序将保留表中的最小id(在您的情况下为1
)。如果要保留最高ID值,则需要将排序顺序更改为over (order by c1.id desc)