【问题标题】:How to delete all records returned by a subquery?如何删除子查询返回的所有记录?
【发布时间】:2017-01-30 21:13:02
【问题描述】:

我想删除某个查询返回的所有记录,但我想不出正确的方法来执行此操作。但是,我尝试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 不是唯一的(该表中也没有其他列是全局唯一的)

【问题讨论】:

  • 你需要一个相关的子查询。

标签: sql oracle sql-delete


【解决方案1】:

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

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

【讨论】:

  • 只有在 column 是唯一值的情况下才有效,不幸的是它不是我的情况。我可以获得唯一记录的唯一方法是聚合所有 50 列并在 columnA 上使用 MAX() 函数
【解决方案2】:

想必你想用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 值,即使这也不能保证有效(尽管可以轻松修改条件以处理此问题)。

【讨论】:

  • 它不是唯一的,这就是问题所在:) 唯一性只能通过聚合所有 50 列以及在 columnA 上使用 MAX() 来实现。第二种解决方案看起来很有趣,我会尝试一下。
【解决方案3】:

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

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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-26
    • 2021-08-02
    • 2014-06-19
    • 1970-01-01
    相关资源
    最近更新 更多