Sql server 具有多个连接的复杂选择逻辑

Sql server 具有多个连接的复杂选择逻辑,sql-server,sql-server-2008,tsql,sql-server-2012,Sql Server,Sql Server 2008,Tsql,Sql Server 2012,我正在尝试处理我正在编写的查询中的逻辑 在使用删除之前,我想确保这是正确的 我想删除选择A中的所有行,其中A.xxxId存在于B中,B.YYYYD存在于C中,但C.YYYYD不存在于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.xxx

我正在尝试处理我正在编写的查询中的逻辑

在使用删除之前,我想确保这是正确的

我想删除选择A中的所有行,其中A.xxxId存在于B中,B.YYYYD存在于C中,但C.YYYYD不存在于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)
谢谢

这个查询有效吗? 对 但在这样做之前,请确保您创建了一个备份,以防出错

为备份准备表定义:

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);

只有你才能知道查询是否有效!在更新为DELETE之前,将查询作为SELECT运行是一个好主意。正如其他人指出的那样,备份也是确保您可以恢复任何意外删除的一种好方法

您也可以使用。我的示例使用以下示例数据:

样本数据

使用事务,您可以执行查询、捕获输出并回滚更改。此示例使用SQL Server创建的。这是一个临时表,除非存储结果,否则它们将丢失

范例

将回滚替换为提交将使您的更改成为数据库的永久部分

在实践中,我将这种方法与已经建议的其他方法相结合

编辑:在我的原始版本中,我使用了一个表变量,不知道这些变量不包括在事务中。请参阅优秀的SQL Server Central上的这篇文章,了解其原因


更新:重读我的答案后,我觉得我的开场白有点厚脸皮。我想说的是,非常糟糕的是,关注这里提供的技术比实际答案更重要

DELETE语句中的OUTPUT INTO子句最好是保存已删除的数据。因此,命令OUTPUT DELETED.*INTO将删除A中的行,并将这些删除的行插入临时备份表?在我看来,它将执行您所说的操作。
/* 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)
;
/* 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
    ;