如何删除子查询返回的所有记录?
How to delete all records returned by a subquery?
我想删除某个查询返回的所有记录,但我想不出合适的方法来执行此操作。然而,我尝试 DELETE FROM mytable WHERE EXISTS (subquery)
,删除了 table 中的所有记录,而不仅仅是子查询选择的记录。
我的子查询如下所示:
SELECT
MAX(columnA) as columnA,
-- 50 other columns
FROM myTable
GROUP BY
-- the 50 other columns above
having count(*) > 1;
这应该很容易,但我现在脑子里卡住了。感谢您提出任何建议。
编辑:columnA 不是唯一的(table 中的其他列也不是全局唯一的)
如果您需要删除 table 的所有行,以便给定字段的值在查询结果中,您可以使用类似
delete table
my column in ( select column from ...)
据推测,您想使用 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
在 table 中 全局 是唯一的。不然你就得加把劲了
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
值(尽管可以轻松修改条件以处理此问题),即使这样也不能保证有效。
唯一性仅由一组列保证的另一种解决方案:
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)
我想删除某个查询返回的所有记录,但我想不出合适的方法来执行此操作。然而,我尝试 DELETE FROM mytable WHERE EXISTS (subquery)
,删除了 table 中的所有记录,而不仅仅是子查询选择的记录。
我的子查询如下所示:
SELECT
MAX(columnA) as columnA,
-- 50 other columns
FROM myTable
GROUP BY
-- the 50 other columns above
having count(*) > 1;
这应该很容易,但我现在脑子里卡住了。感谢您提出任何建议。
编辑:columnA 不是唯一的(table 中的其他列也不是全局唯一的)
如果您需要删除 table 的所有行,以便给定字段的值在查询结果中,您可以使用类似
delete table
my column in ( select column from ...)
据推测,您想使用 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
在 table 中 全局 是唯一的。不然你就得加把劲了
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
值(尽管可以轻松修改条件以处理此问题),即使这样也不能保证有效。
唯一性仅由一组列保证的另一种解决方案:
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)