2016-09-22 75 views
0

我想删除某个查询返回的所有记录,但我找不到一个正确的方法来做到这一点。然而,我尝试了DELETE FROM mytable WHERE EXISTS (subquery),它删除了表中的所有记录,而不是子查询选择的记录。如何删除子查询返回的所有记录?

我的子查询是这样的:

SELECT 
MAX(columnA) as columnA, 
-- 50 other columns 
FROM myTable 
GROUP BY 
-- the 50 other columns above 
having count(*) > 1; 

这应该是很容易的,但我的心只是坚持现在。我很感激任何建议。

编辑:columnA不是唯一的(也即表中没有其他的列是全球唯一)

+0

你需要一个相关子查询。 – jarlh

回答

1

据推测,要使用in

DELETE FROM myTable 
    WHERE columnA IN (SELECT MAX(columnA) as columnA 
         FROM myTable 
         GROUP BY -- the 50 other columns above 
         HAVING count(*) > 1 
        ); 

这假定columnA全球表中唯一。否则,你将不得不努力工作。

DELETE FROM myTable t 
    WHERE EXISTS (SELECT 1 
        FROM (SELECT MAX(columnA) as columnA, 
           col1, col2, . . . 
         FROM myTable 
         GROUP BY -- the 50 other columns above 
         HAVING count(*) > 1 
         ) t2 
        WHERE t.columnA = t2.columnA AND 
         t.col1 = t2.col1 AND 
         t.col2 = t2.col2 AND . . . 
       ); 

而且,即使这是不能保证工作,如果任何列具有NULL值(虽然条件可以很容易地修改,以处理这一点)。

+0

这不是唯一的,这是问题:)唯一性只能通过汇总所有50列以及使用MAX()在列A上。第二个解决方案看起来很有趣,我会尝试。 – daZza

0

如果你需要删除表中的所有行,使得在给定字段的值是结果查询时,您可以使用类似

delete table 
my column in (select column from ...) 
+0

这只有在列是唯一值时才有效,不幸的是它不在我的情况中。唯一可以获得唯一记录的方法是汇总所有50列,并在列A上使用MAX()函数。 – daZza

0

如果唯一性仅由一组列的保证的另一个解决方案:

delete table1 where (col1, col2, ...) in (
    select min(col1), col2, ... 
    from table1 
    where... 
    group by col2, ... 
) 

Null值将被忽略,不被删除。

要做到这一点,你可以试试

with data (id, val1, val2) as 
(
select 1, '10', 10 from dual union all 
select 2, '20', 21 from dual union all 
select 2, null, 21 from dual union all 
select 2, '20', null from dual 
) 
-- map null values in column to a nonexistent value in this column 
select * from data d where (d.id, nvl(d.val1, '#<null>')) in 
(select dd.id, nvl(dd.val1, '#<null>') from data dd)