簡體   English   中英

如何刪除表中具有另一個表中相應記錄的所有記錄

[英]How do I delete all the records in a table that have corresponding records in another table

我有兩個表A和B.我想刪除在以下查詢中返回的表A中的所有記錄:

SELECT A.*
FROM A , B
WHERE A.id = B.a_id AND
    b.date < '2008-10-10'

我努力了:

DELETE A 
WHERE id in (
    SELECT a_id 
    FROM B 
    WHERE date < '2008-10-10')

但這只有在內部選擇實際返回一個值時才有效(如果結果集為空則不行)

注意:這必須適用於SQLServer和MySQL

編輯:更多信息

以上刪除在SQLServer上100%有效

在MySQL上運行時,我得到一個“SQL語法錯誤”消息,指出SELECT的開始是問題。 如果我用(1,2)替換內部選擇,那么它的工作原理。

@Kibbee你是對的,如果內部選擇返回行,它實際上沒有區別。

@Fred我得到一個“不唯一的table.alias:a”消息

我認為這應該有效(無論如何都適用於MySQL):

DELETE a.* FROM A a JOIN B b ON b.id = a.id WHERE b.date < '2008-10-10';

沒有別名:

DELETE A.* FROM A JOIN B ON B.id = A.id WHERE B.date < '2008-10-10';

我不確定你的方法失敗的原因。 如果內部查詢返回空集,則第一個查詢也應返回空集。 我不認為@Fred的解決方案是正確的,因為他似乎加入了錯誤的專欄。

或者您可以切換到具有相關子查詢的存在語法...

Delete A 
From A
Where Exists 
      (Select * From B 
       Where B.Id = A.Id
         And B.date < '2008-10-10');

根據查詢優化器的智能程度,(以及子查詢將返回表B中的記錄數),這可能會更快,因為存在不需要完全生成完整的結果集...它可以盡快停止因為它找到了一條記錄......

你離答案還不遠!

發布后:刪除表A和B上的別名

DELETE FROM A
WHERE A.id in (
    SELECT B.a_id 
    FROM B
    WHERE B.date < '2008-10-10');

您還可以在子表中使用ON CASCADE,以便在父表中刪除行時,它會自動刪除子表中的子行。 這樣,刪除父行時無需擔心引用完整性。

delete from a inner join b on a.id = b.a_id and b.date < '2008-10-10'

MYSQL和MSSQL中的另一個選項,但它的做法很好:

select b.ID
into #T
from 
    [Table b] with (nolock) 
where 
  b.date > '2008-10-10'

if exists (select * from #T with (nolock))
    delete from [Table a] where a.id in (select id from #T with (nolock))
    drop table #T

根據你對DELETE語句的描述,你想刪除表A中的空orphants嗎?

DELETE A.*
FROM A 
LEFT JOIN B ON A.id = B.a_id AND b.date > '2008-10-10'
WHERE b.id IS NULL

(請注意B中倒入的倒入方式)

在這種情況下應該做的伎倆。 我不確定MSSQL如何處理加入 - 刪除,但我想它應該以相同的方式工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM