【问题标题】:Delete all rows in a table based on another table根据另一个表删除一个表中的所有行
【发布时间】:2010-12-08 03:04:43
【问题描述】:

我似乎不记得这个查询了!

我想删除 table1 中 ID 与 Table2 相同的所有行。

所以:

DELETE table1 t1
 WHERE t1.ID = t2.ID

我知道我可以执行 WHERE ID IN (SELECT ID FROM table2),但如果可能,我想使用 JOIN 执行此查询。

【问题讨论】:

  • 为什么要加入?
  • 你打算怎么处理这个问题:stackoverflow.com/questions/1590709/…
  • 因为连接通常更快。
  • @tster 可能是需要删除的ids临时表
  • @HLGEM 您是说查询优化器不够聪明,无法像执行联接一样快地执行简单的“从 X 中删除 X.Y IN(从 Bar 中选择 Foo)”吗?我会相信优化器而不是直觉。

标签: sql


【解决方案1】:
DELETE t1 
FROM Table1 t1
JOIN Table2 t2 ON t1.ID = t2.ID;

我总是在删除语句中使用别名,因为它可以防止意外

DELETE Table1 

在运行之前未能突出显示整个查询。

【讨论】:

  • 主要支持“始终使用别名”评论。好主意。
【解决方案2】:
DELETE Table1
FROM Table1
INNER JOIN Table2 ON Table1.ID = Table2.ID

【讨论】:

  • 有人在超过 10+ 百万行的大表上测试过这个吗?
  • 我也想知道同样的事情。表现如何?
【解决方案3】:

在 ANSI SQL 中没有解决方案在删除中使用连接,AFAIK。

DELETE FROM Table1
WHERE Table1.id IN (SELECT Table2.id FROM Table2)

稍后编辑

其他解决方案(有时执行速度更快):

DELETE FROM Table1
WHERE EXISTS( SELECT 1 FROM Table2 Where Table1.id = Table2.id)

【讨论】:

  • 他的问题最后指出他想使用连接而不是 IN 子句。
【解决方案4】:

PostgreSQL 实现将是:

DELETE FROM t1
USING t2
WHERE t1.id = t2.id;

【讨论】:

    【解决方案5】:

    试试这个:

    DELETE Table1
    FROM Table1 t1, Table2 t2
    WHERE t1.ID = t2.ID;
    

    DELETE Table1
    FROM Table1 t1 INNER JOIN Table2 t2 ON t1.ID = t2.ID;
    

    【讨论】:

      【解决方案6】:

      我认为如果您尝试这样做,您可能会获得更多性能

      DELETE FROM Table1
      WHERE EXISTS (
        SELECT 1
        FROM Table2
        WHERE Table1.ID = Table2.ID
      )
      

      【讨论】:

        【解决方案7】:

        这将删除Table1 中符合条件的所有行:

        DELETE Table1 
        FROM Table2 
        WHERE Table1.JoinColumn = Table2.JoinColumn And Table1.SomeStuff = 'SomeStuff'
        

        【讨论】:

          【解决方案8】:

          发现这个link很有用

          从那里复制

          通常,人们想根据另一个表中的条件从一个表中删除一些记录。如何从其中一个表中删除而不删除两个表中的记录?

          DELETE DeletingFromTable
               FROM DeletingFromTable INNER JOIN CriteriaTable
               ON DeletingFromTable.field_id = CriteriaTable.id
               WHERE CriteriaTable.criteria = "value";
          

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

           DELETE subscribers, subscriptions
               FROM subscribers INNER JOIN subscriptions 
                 ON subscribers.id = subscriptions.subscriber_id
               INNER JOIN magazines 
                 ON subscriptions.magazine_id = magazines.id
               WHERE subscribers.name='Wes';
          

          删除带有连接的记录也可以使用 LEFT JOIN 和 WHERE 来查看连接的表是否为 NULL,这样您就可以删除一个表中没有匹配的记录(例如准备添加关系。)示例帖子即将发布。

          【讨论】:

            【解决方案9】:

            由于 OP 不要求特定数据库,因此最好使用符合标准的语句。 只有 MERGE 符合 SQL 标准,用于在连接目标表时删除(或更新)行。

            merge table1 t1
                using (
                    select t2.ID
                        from table2 t2
                ) as d
                on t1.ID = d.ID
                when matched then delete;
            

            MERGE 具有更严格的语义,可以防止出现DELETE ... FROM 可能不会注意到的一些错误情况。它强制匹配的“唯一性”:如果源中的许多行(using 中的语句)与目标中的同一行匹配,则必须取消合并并且 SQL 引擎必须引发错误。

            【讨论】:

            • 这比删除连接结构更干净
            【解决方案10】:

            根据另一个表删除表记录

                 Delete From Table1 a,Table2 b where a.id=b.id
            
                Or
            
                  DELETE FROM Table1
                WHERE Table1.id IN (SELECT Table2.id FROM Table2)
            
              Or
            
                    DELETE Table1
                 FROM Table1 t1 INNER JOIN Table2 t2 ON t1.ID = t2.ID;
            

            【讨论】:

              【解决方案11】:

              我经常做类似以下虚构示例的事情。 (此示例来自在 Linux 上运行的 Informix SE。)

              此示例的重点是根据 real_estate 表中的信息删除所有房地产减免交易记录——因为减免应用程序存在错误。

              这里last_update != null表示账户未关闭,res_exempt != 'p'表示账户不是个人财产(商业设备/家具)。

              delete from trans 
              where   yr = '16'
              and     tran_date = '01/22/2016'
              and     acct_type = 'r'
              and     tran_type = 'a'
              and     bill_no in
              (select acct_no from real_estate where last_update is not null
               and res_exempt != 'p');
              

              我喜欢这种方法,因为过滤条件 - 至少对我而言 - 在创建查询时更易于阅读,并且在几个月后当我查看它并想知道我在想什么时更容易理解。

              【讨论】:

                【解决方案12】:

                引用MSDN T-SQL DELETE(示例D):

                DELETE FROM Table1
                FROM Tabel1 t1
                   INNER JOIN Table2 t2 on t1.ID = t2.ID
                

                【讨论】:

                  【解决方案13】:

                  我知道这是旧的,但只是指向使用此 ass 引用的任何人的指针。我刚刚尝试过,如果您使用的是 Oracle,则 JOIN 在 DELETE 语句中不起作用。 您会收到以下消息:

                  ORA-00933:SQL 命令未正确结束。

                  【讨论】:

                  【解决方案14】:

                  虽然 OP 不想使用“in”语句,但作为对 Ankur Gupta 的回复,这是我发现删除一个表中不存在于另一个表中的记录的最简单方法,在一个对多关系:

                  DELETE
                  FROM Table1 as t1
                  WHERE ID_Number NOT IN
                  (SELECT ID_Number FROM Table2 as t2)
                  

                  对我来说,在 Access 2016 中工作就像一个魅力。

                  【讨论】:

                    【解决方案15】:
                    delete
                        table1
                    from 
                        t2
                    where
                        table1.ID=t2.ID
                    

                    适用于 mssql

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 2010-12-19
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多