2016-01-08 46 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:重读我的答案让我觉得我的开头句有些厚颜无耻。我试图做的非常糟糕的一点是,关注这里提供的技术比实际的答案更重要。