我一直在SQL Server中遇到这种DELETE FROM FROM
语法,并且不得不提醒自己它的作用。
DELETE FROM tbl
FROM #tbl
INNER JOIN tbl ON fk = pk AND DATEDIFF(day, #tbl.date, tbl.Date) = 0
编辑:为了使大多数评论和建议答案有意义,原始问题具有以下查询:
DELETE FROM tbl
FROM tbl2
答案 0 :(得分:4)
据我了解,您将使用类似 的结构,在该结构中,您将根据from查询的结果来限制从第一张表中删除哪些行。但是要做到这一点,您需要在两者之间建立关联。
在您的示例中,没有关联,这实际上是一种交叉连接,这意味着“对于tbl2中的每一行,删除tbl1中的每一行”。换句话说,它将删除第一张表中的每一行。
这里是一个例子:
declare @t1 table(A int, B int)
insert @t1 values (15, 9)
,(30, 10)
,(60, 11)
,(70, 12)
,(80, 13)
,(90, 15)
declare @t2 table(A int, B int)
insert @t2 values (15, 9)
,(30, 10)
,(60, 11)
delete from @t1 from @t2
结果为空@ t1。
另一方面,这只会删除匹配的行:
delete from @t1 from @t2 t2 join @t1 t1 on t1.A=t2.A
答案 1 :(得分:2)
我以前从没见过。 DELETE
的文档告诉我们:
FROM table_source指定附加的FROM子句。这个 Transact-SQL扩展到DELETE允许从 并从表中删除相应的行 第一个FROM子句。
可以使用此扩展名(指定连接)来代替子查询 在WHERE子句中以标识要删除的行。
后来在我们找到的同一文档中
D。使用联接和子查询到一个表中的数据以删除其中的行 另一个表以下示例显示了两种删除表中行的方法 一个表基于另一个表中的数据。在两个示例中,来自 AdventureWorks2012数据库中的SalesPersonQuotaHistory表 根据存储在SalesPerson中的最新销售额删除 表。第一条DELETE语句显示与ISO兼容的子查询 解决方案,第二个DELETE语句显示Transact-SQL FROM 连接两个表的扩展名。
通过这些示例来展示差异
-SQL-2003标准子查询
DELETE FROM Sales.SalesPersonQuotaHistory
WHERE BusinessEntityID IN
(SELECT BusinessEntityID
FROM Sales.SalesPerson
WHERE SalesYTD > 2500000.00);
-Transact-SQL扩展
DELETE FROM Sales.SalesPersonQuotaHistory
FROM Sales.SalesPersonQuotaHistory AS spqh
INNER JOIN Sales.SalesPerson AS sp
ON spqh.BusinessEntityID = sp.BusinessEntityID
WHERE sp.SalesYTD > 2500000.00;
在这种情况下,第二个FROM
提到了同一张表。这是获得类似于可更新的cte 或派生表
在D部分的第三个示例中,文档清楚地说明了
-无需多次提及目标表。
DELETE spqh
FROM
Sales.SalesPersonQuotaHistory AS spqh
INNER JOIN Sales.SalesPerson AS sp
ON spqh.BusinessEntityID = sp.BusinessEntityID
WHERE sp.SalesYTD > 2500000.00;
因此,给我的印象是,这样做的唯一原因是使用真实表的名称作为DELETE的目标而不是别名。