根据与其他表的比较删除某些行

如果表中的数据与其他表中的某些数据匹配(或不匹配),则可以从表中获取数据。

让我们假设我们想要从 Source 加载到 Target 后来自 Source 的 DELETEdata。

DELETE FROM Source
WHERE  EXISTS ( SELECT 1 -- specific value in SELECT doesn't matter
               FROM Target
               Where Source.ID = Target.ID )

最常见的 RDBMS 实现(例如 MySQL,Oracle,PostgresSQL,Teradata)允许在 DELETE 期间连接表,从而允许在紧凑语法中进行更复杂的比较。

增加原始场景的复杂性,我们假设 Aggregate 每天从 Target 构建一次,并且不包含相同的 ID,但包含相同的日期。让我们也假设我们要删除的源数据只是汇总填充的一天后。

在 MySQL,Oracle 和 Teradata 上,可以使用以下方法完成:

DELETE FROM Source
WHERE  Source.ID = TargetSchema.Target.ID
       AND TargetSchema.Target.Date = AggregateSchema.Aggregate.Date

在 PostgreSQL 中使用:

DELETE FROM Source
USING  TargetSchema.Target, AggregateSchema.Aggregate
WHERE  Source.ID = TargetSchema.Target.ID
       AND TargetSchema.Target.DataDate = AggregateSchema.Aggregate.AggDate

这实质上导致 Source,Target 和 Aggregate 之间的 INNER JOIN。当目标中存在相同的 ID 时,将在源上执行删除,并且这些 ID 中存在的日期也存在于聚合中。

也可以编写相同的查询(在 MySQL,Oracle,Teradata 上):

DELETE Source
FROM   Source, TargetSchema.Target, AggregateSchema.Aggregate
WHERE  Source.ID = TargetSchema.Target.ID
       AND TargetSchema.Target.DataDate = AggregateSchema.Aggregate.AggDate

在一些 RDBMS 实现(例如 Oracle,MySQL)的 Delete 语句中可能会提到显式连接,但在所有平台上都不支持(例如 Teradata 不支持它们)

比较可以设计为检查不匹配的情况,而不是匹配所有语法样式的情况(请参阅下面的 NOT EXISTS

DELETE FROM Source
WHERE NOT EXISTS ( SELECT 1 -- specific value in SELECT doesn't matter
               FROM Target
               Where Source.ID = Target.ID )