用于删除具有相同值集的行的SQL

时间:2012-11-17 02:20:36

标签: sql oracle

我有一张这样的表:

ID, ItemsID
1   2                                                                       
1   3     
1   4   
2   3  
2   4  
2   2

我想删除ID=2之类的元组,因为在我的情况下2,3,43,4,2相同。

我该如何使用SQL?

3 个答案:

答案 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
  )
)

SQLfiddle

您可能需要调整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)