在两个以上的表上使用内部联接删除查询

时间:2012-11-23 05:03:56

标签: sql db2

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

3 个答案:

答案 0 :(得分:11)

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

  

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引用。我们不想删除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
    );
    
  4. 根据您的要求,您可以合并其中一个查询。

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

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

答案 1 :(得分:1)

基于'Using SQL to delete rows from a table using INNER JOIN to another table'

  

关键是您指定要删除的表的名称   作为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';

答案 2 :(得分: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 )

这应该有效