2

我想在两个以上的表上使用内部联接从表中删除记录。假设我有 A、B、C、D 表,A 的 pk 在所有其他提到的表中共享。然后如何编写删除查询以使用表 B 和 A 上的内部连接从表 D 中删除记录,因为条件是从这两个表中获取的。从 DB2 的角度来看,我需要这个查询。由于它们的限制,我没有使用 IN 子句或 EXISTS。

4

3 回答 3

13

根据您的描述,我将架构视为:

A(pk_A, col1, col2, ...)

B(pk_B, fk_A, col1, col2, ..., 外键 fk_A 引用 A(pk_A))

C(pk_c, fk_A, col1, col2, ..., 外键 fk_A 引用 A(pk_A))

D(pk_d, fk_A, col1, col2, ..., 外键 fk_A 引用 A(pk_A))

正如您所说,如果使用 IN 子句,DB2 将只允许删除 1000 行。我不了解 DB2,但 Oracle 在 IN 子句中只允许 1000 个手动值。至少在Oracle 中对子查询结果没有这样的限制。EXISTS 不应该成为任何数据库的问题,包括 Oracle 和 DB2 只检查行的存在,无论是一百万行还是一百万行。

从表 D 中删除数据的三种情况:

  1. 您想从表 D 中删除数据,其中 fk_A(自然)使用列 A.pk_A 引用表 A 中的记录:

    DELETE FROM d
    WHERE EXISTS (
           SELECT 1
             FROM a
            WHERE a.pk_A = d.fk_A
    );
    
  2. 您想从表 D 中删除数据,其中 fk_A 引用表 A 中的记录,并且表 A 中的记录也由列 B.fk_A 引用。我们不想从 D 中删除 A 中但不在 B 中的数据。我们可以这样写:

    DELETE FROM d
    WHERE EXISTS (
           SELECT 1
             FROM a
       INNER JOIN b ON a.pk_A = b.fk_A
            WHERE a.pk_A = d.fk_A
    );
    
  3. 第三种情况是当我们必须删除表 D 中引用表 A 中记录的数据时,并且 A 中的记录也被列 B.fk_A 和表 C.fk_A 引用。我们只想从表 D 中删除该数据,在所有四个表 A、B、C 和 D 中都是通用的。我们可以这样写:

    DELETE FROM d
    WHERE EXISTS (
           SELECT 1
             FROM a
       INNER JOIN b ON a.pk_A = b.fk_A
       INNER JOIN c ON a.pk_A = c.fk_A
            WHERE a.pk_A = d.fk_A
    );
    

根据您的要求,您可以合并这些查询之一。

请注意,如果子查询检索多于一行,“=”运算符将返回错误。另外,我不知道 DB2 是否支持 ANY 或 ALL 关键字,因此我使用了一个简单但功能强大的 EXISTS 关键字,它比 IN、ANY 和 ALL 执行得更快。

此外,您可以在此处观察到 EXISTS 子句中的子查询使用“SELECT 1”,而不是“SELECT a.pk”或其他一些列。这是因为 EXISTS 在任何数据库中只查找行的存在,而不是列内的任何特定值。

于 2012-11-23T07:45:12.403 回答
1

基于“使用 SQL 将使用 INNER JOIN 的表中的行删除到另一个表”

关键是您将要删除的表的名称指定为 SELECT。因此,JOIN 和 WHERE 进行选择和限制,而 DELETE 进行删除。不过,您不仅限于一张桌子。如果您具有多对多关系(例如,杂志和订阅者,通过订阅连接)并且您要删除订阅者,您还需要从连接模型中删除所有潜在记录。

DELETE subscribers
     FROM subscribers INNER JOIN subscriptions 
       ON subscribers.id = subscriptions.subscriber_id
     INNER JOIN magazines 
       ON subscriptions.magazine_id = magazines.id
     WHERE subscribers.name='Wes';
于 2017-06-28T11:08:15.323 回答
0
delete from D 
where fk  = (select d.fk from D d,A a,B b where a.pk = b.fk and b.fk = d.fk )

这应该工作

于 2012-11-23T05:09:55.667 回答