2016-01-08 44 views
2

我正試圖通過我正在寫的查詢中的邏輯工作。具有多個連接的複雜選擇邏輯

我想在使用DELETE之前確保我有這個正確的。

我想刪除(選擇)中的所有行,其中a.xxxId存在於B和b.yyyId存在於C,但其中c.yyyId不D.

將這項工作的查詢存在

-- all a that are in b, 
-- that are in c, 
-- that are NOT in d 

-- change to DELETE 

SELECT a.* 
FROM A a 
     JOIN B b ON a.xxxId = b.xxxId 
     JOIN C c ON b.yyyId = c.yyyId 
WHERE NOT EXISTS (SELECT * FROM D d WHERE c.yyyId = d.yyyId) 

謝謝!

+0

在我看來,它會去做你說的你想要的東西。 – shawnt00

回答

3
  • 此查詢是否有效?
  • 是的。

但在這之前,請確保您創建一個備份,以防發生廢話。

準備一個表定義備份:

SELECT TOP (0) * 
INTO TemporaryBackupTable 
FROM a; 

然後運行DELETE語句,這也將插入刪除的記錄到準備備份表。

DELETE a.* 
OUTPUT DELETED.* INTO TemporaryBackupTable 
FROM A a 
     JOIN B b ON a.xxxId = b.xxxId 
     JOIN C c ON b.yyyId = c.yyyId 
WHERE NOT EXISTS (SELECT * FROM D d WHERE c.yyyId = d.yyyId); 
+1

DELETE語句的OUTPUT INTO子句最好是保存被刪除的數據 –

+1

@KM。同意。讓我更新我的答案。 –

+0

,以便命令OUTPUT DELETED。* INTO從A刪除行並將這些刪除的行插入到temporaryBackupTable中? – SkyeBoniwell

2

只有您可以判斷查詢是否有效!在更新到DELETE之前將查詢作爲SELECT運行是個不錯的主意。正如其他人指出的那樣,採取備份也是確保您可以恢復任何意外刪除的好方法。您可以使用TRANSACTIONS。我的示例使用此樣本數據:

樣本數據

/* We'll use a temp table to test the transaction. 
*/ 
CREATE TABLE #Sample  
    (
     Id INT 
    ) 
; 

/* Populate sample values. 
*/ 
INSERT INTO #Sample 
    (
     Id 
    ) 
VALUES 
    (1), 
    (2), 
    (3), 
    (4), 
    (5) 
; 

使用事務,你可以執行查詢,捕獲輸出和回滾的變化。本示例使用由SQL Server創建的DELETED table。這是一個臨時表格,除非您存儲結果將會丟失。

/* Wrapping your statements in a transaction allows you to 
* rollback the results. 
*/ 
BEGIN TRANSACTION xy; 

    /* The output clause allows you to inspect 
    * the deleted records, using the deleted table. 
    * This table is created by SQL Server for you. 
    */ 
    DELETE 
    FROM 
     #Sample 
    OUTPUT 
     deleted.* 
    WHERE 
     Id > 3 
    ; 

ROLLBACK TRANSACTION xy; 


    /* Outside the transaction the table still contains the 
    * original records. 
    */ 
    SELECT 
     * 
    FROM 
     #Sample 
    ; 

更換ROLLBACK與COMMIT將進行更改數據庫的永久部分。

在實踐中,我將這種方法與其他人已經提出的方法結合起來。

編輯:在我的原始版本中,我使用了一個表變量,不知道這些不包含在事務中。出於這個原因,在出色的SQL Server Central上看到這個blog

UPDATE:重讀我的答案讓我覺得我的開頭句有些厚顏無恥。我試圖做的非常糟糕的一點是,關注這裏提供的技術比實際的答案更重要。