Oracle删除与多个值匹配的行

Posted

技术标签:

【中文标题】Oracle删除与多个值匹配的行【英文标题】:Oracle Delete Rows Matching On Multiple Values 【发布时间】:2009-02-02 17:28:28 【问题描述】:

我想做这样的事情:

DELETE FROM student WHERE
student.course, student.major IN
(SELECT schedule.course, schedule.major FROM schedule)

但是,您似乎只能将一列与 IN 运算符一起使用。真的吗?看起来像这样的查询应该是可能的。

【问题讨论】:

【参考方案1】:

不,你只需要括号:

DELETE FROM student WHERE
(student.course, student.major) IN
(SELECT schedule.course, schedule.major FROM schedule)

【讨论】:

所以这实际上具有误导性,我认为它的非直觉性本质上是不正确的。如果您的行包含空值 IN 不起作用。我想,这对于 null 的含义是有意义的,但与例如减号的工作原理完全不一致。【参考方案2】:

您也可以使用 EXISTS 子句:

DELETE FROM student WHERE
EXISTS
(
  SELECT 1 FROM schedule 
  WHERE schedule.course=student.course 
  AND schedule.major=student.major
)

【讨论】:

+1; WHERE EXISTS 是一种被严重低估的机制,比使用 IN 要好得多 @Brian:(我意识到我回复你的评论有点晚了!)你为什么说 EXISTS 比 IN 好得多? 一个很好的问题。我的理解是,在性能方面这是一个不错的选择,但在证据方面我提供的很少。也就是说,我设法找到了这个:techrepublic.com/article/… 其他可能更有帮助的链接:techonthenet.com/sql/exists.php 和 ***.com/questions/24929/… 好吧,IN 子句中的结果值也有可能过多,我过去曾见过这会导致问题......比如超过 1024....【参考方案3】:
DELETE FROM student WHERE
(student.course, student.major) IN
(SELECT schedule.course, schedule.major FROM schedule)

在 where 子句中为您的条款加上括号。干杯!

【讨论】:

【参考方案4】:

在 Oracle 中,您可以从内联视图中执行删除操作,但它通常需要一个外键来确保删除该行的表中的一行不能由视图中的多行表示.

create table parent (id number primary key);
create table child (id number primary key, parent_id number references parent);
insert into parent values(1);
insert into child values(2,1);
delete from (select * from parent p, child c where c.parent_id = p.id);

【讨论】:

【参考方案5】:

请注意,如果任何属性为空,则该行被认为不是 IN。也就是说,如果课程相同,并且学生和时间表专业都为空,则不会删除行。

如果某个属性(例如major)可能为null,并且您希望null = null 为true,请尝试:

DELETE
FROM student
WHERE (student.course, NVL(student.major,'sOmeStRinG') )
IN (SELECT schedule.course, NVL(schedule.major,'sOmeStRinG') FROM schedule)

【讨论】:

【参考方案6】:

下面的语法适用于 SQLServer 但我相信它是标准的 sql 但正如 cmets 中指出的,这是非标准实现,Oracle 目前不支持。

留作参考

delete s
from 
    student s 
    inner join schedule sch
    on s.course=sch.course 
    and s.major = sch.major

【讨论】:

不,标准 SQL 只支持 DELETE 中的一张表。 mysql 和 Microsoft SQL Server 支持多表 DELETE 作为标准的扩展,但 Oracle 不支持。 表的 SQL 标准概念并不仅限于表。它通常包括视图。某些视图是可更新的,并且通过扩展,是可删除的。 感谢 cmets,很高兴了解 DB 实现的差异。我已更新我的答案以包含您的观点

以上是关于Oracle删除与多个值匹配的行的主要内容,如果未能解决你的问题,请参考以下文章

SQLITE3 - 删除具有相同值的多个列的行

MYSQL - 将具有多个重复值的行组合起来,然后删除重复项

通过从多个列中删除匹配的电子邮件域来过滤 Pandas 数据框

oracle 将一列数字分为多个为1的行

已更新或删除的行值要么不能使该行成为唯一行,要么改变了多个行,如何解决

sql server"已更新或删除的行值要么不能使该行成为唯一行,要么改变了多个行" 解决方案