从两个表中删除“等效”数据

时间:2013-03-06 11:54:55

标签: sql-server tsql sql-server-2012

我需要在SQL Server 2012过程中执行以下伪逻辑,基于表变量和声明为这样的表:

DECLARE @tmp TABLE
    (
    ID int IDENTITY(1,1),
    UserID int NOT NULL,
    SgsID int NOT NULL
    )

CREATE TABLE #Table1
    (
    ID int IDENTITY(1,1),
    UserID int NOT NULL,
    SgsID int NOT NULL
    )
  1. 表变量@tmp
  2. 中的每一行数据
  3. Table1 UserID/SgsID组合UserID/SgsID组合Table1中删除行
  4. UserID/SgsID
  5. 中删除已从@tmp中删除的Table1个组合

    我一直在研究不同的方法,例如使用OUTPUT INTOINTERSECT,但不能编写一个删除两个表的查询(实际上我认为它甚至不可能)。

    我已经通过使用以下代码实现了上述步骤,但是,我想知道是否有任何T-SQL专家可以建议更简洁/有效的方法?

    请参阅SQLFiddle for online version

    CREATE TABLE #Table1
        (
        ID int IDENTITY(1,1),
        UserID int NOT NULL,
        SgsID int NOT NULL
        )
    
    INSERT INTO #Table1 (UserID, SgsID) VALUES (5, 99)
    INSERT INTO #Table1 (UserID, SgsID) VALUES (10, 89)
    INSERT INTO #Table1 (UserID, SgsID) VALUES (150, 79)
    INSERT INTO #Table1 (UserID, SgsID) VALUES (200, 69)
    INSERT INTO #Table1 (UserID, SgsID) VALUES (250, 59)
    SELECT * FROM #Table1 
    
    DECLARE @tmp TABLE
        (
        ID int IDENTITY(1,1),
        UserID int NOT NULL,
        SgsID int NOT NULL
        )
    
    INSERT INTO @tmp (UserID, SgsID) VALUES (150, 79)
    INSERT INTO @tmp (UserID, SgsID) VALUES (200, 69)
    INSERT INTO @tmp (UserID, SgsID) VALUES (250, 59)
    INSERT INTO @tmp (UserID, SgsID) VALUES (999, 49)
    SELECT * FROM @tmp
    
    DECLARE @tbl_commonRows TABLE (UserID int, SgsID int)
    INSERT INTO @tbl_commonRows 
        (
        UserID,
        SgsID
        ) 
    SELECT 
        UserID,
        SgsID 
    FROM
        #Table1
    INTERSECT 
    SELECT
        UserID,
        SgsID
    FROM
        @tmp 
    
    DELETE FROM 
        #Table1 
    WHERE 
        (ID IN (
            SELECT 
                ID 
            FROM 
                #Table1 t1 INNER JOIN
                @tbl_commonRows c ON c.UserID = t1.UserID AND c.SgsID = t1.SgsID))
    
    DELETE FROM
        @tmp
    WHERE
        (ID IN (
            SELECT
                ID
            FROM
                @tmp t2 INNER JOIN
                @tbl_commonrows c ON c.UserID = t2.UserID AND c.SgsID = t2.SgsID))
    
    SELECT * FROM #Table1 
    SELECT * FROM @tmp
    DROP TABLE #Table1
    

3 个答案:

答案 0 :(得分:4)

这是解决方案:

DECLARE @tmp_ids TABLE (
    id1 INT,
    id2 INT
)

INSERT INTO @tmp_ids (id1, id2)
SELECT 
    t1.id,
    t2.id
FROM Table1 t1
INNER JOIN tmp t2
    on (t1.UserID = t2.UserID AND t1.SgsID = t2.SgsID)

DELETE FROM Table1
WHERE id IN (SELECT id1 FROM @tmp_ids)

DELETE FROM tmp
WHERE id IN (SELECT id2 FROM @tmp_ids)

请记住 - 我创建了物理表tmp和Table1

答案 1 :(得分:2)

您可以利用以下事实:OUTPUT命令可以使用多于INSERTED和DELETED列进行删除(但遗憾的是不插入):

    DECLARE @output TABLE (id int) 

    DELETE FROM tbl
    OUTPUT tmp.ID INTO @output(id)
    FROM #Table1 tbl
    JOIN @tmp tmp 
        ON tbl.UserID = tmp.UserID 
        AND tbl.SgsID = tmp.SgsID

    DELETE FROM tmp
    FROM @tmp tmp
    JOIN @Output outp ON tmp.id = outp.id   

答案 2 :(得分:1)

您是否考虑过使用MERGE?可能是另一种选择,语法很好,易于理解。

MERGE (Transact-SQL)