Sql server 删除';等价物';来自两个表的数据

Sql server 删除';等价物';来自两个表的数据,sql-server,tsql,sql-server-2012,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

我需要在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
    )
  • 对于表变量
    @tmp
  • Table1
    中删除行,其中
    UserID/SgsID
    组合匹配
    UserID/SgsID
  • @tmp
    中删除那些已从
    表1
    中删除的
    UserID/SgsID
    组合
  • 我一直在研究不同的方法,例如使用
    输出到
    交集
    ,但无法编写跨两个表删除的查询(事实上,我认为这甚至是不可能的)

    我已经通过使用以下代码实现了上述步骤,但是,我想知道是否有T-SQL专业人士能够建议一种更简洁/高效的方法

    以下是解决方案:

    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和表1

    您考虑过为此使用合并吗?可能是另一种选择,语法很好,也很容易理解


    您可以利用这样一个事实,即输出命令可以使用多于插入和删除的列进行删除(遗憾的是,不是插入):


    它不能正常工作。例如,如果在
    @tmp
    表中有
    (250,100)
    (250,59)
    ,并且在
    #表1
    中有
    (250,59)
    。这两条记录都将从
    @tmp
    中删除,尽管在
    #表1
    中只匹配了
    (250,29)
    ,如果您实际使用我建议的场景对其进行测试,您会发现它在特定情况下不起作用,则应从
    @tmp
    @Sergio中删除…@IvanG Haha,刚刚意识到它在sqlfiddle中工作不正确。但是ssms做的一切都很好。我猜是小提琴bug@Sergio这不可能是SQL Fiddle bug,因为该站点下面有SQL Server,只是通过接口传递数据。无论如何,我在SSMS中测试了您的解决方案,而不是在SQL Fiddle上,该解决方案不适用于我描述的那种情况,希望OP能针对这种情况进行测试。@Sergio的查询是可以的,我误解了他的部分查询,这是可以的,很抱歉……我希望在遇到您的答案时,还没有人发布此解决方案。:)不错,我不知道,谢谢。但是,两个表中的ID列可能不相同,因为在UserID/sgsID中,两个表中的对应ID可能不相同。请问您的代码在这种情况下仍然相关吗?@EvilDr Yes;这实际上是想要输出tmp.ID的一个原因,这样您就知道在执行tmp的delete操作时,您将返回到tmp中的相应行。您是否可以发布一个示例来说明如何使用它?我认为,因为MERGE是基于源表对目标表进行操作的,所以它在这里不合适,因为我们同时对源表和目标表进行操作…?您可以通过使用output子句修改源表来扩展MERGE一点:今天早上玩MERGE-我绝对喜欢它。这是一个多么惊人的增加。与输出合并非常好:-)
    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)
    
        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