Sql server 删除';等价物';来自两个表的数据
我需要在SQL Server 2012过程中基于表变量和声明为表的表执行以下伪逻辑: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
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