SQL Server: УДАЛИТЬ ИЗ таблицы ИЗ таблицы - PullRequest
1 голос
/ 05 июня 2019

Я все время сталкиваюсь с этим синтаксисом DELETE FROM FROM в SQL Server, и мне приходится напоминать себе, что он делает.

DELETE FROM tbl
FROM #tbl
  INNER JOIN tbl ON fk = pk AND DATEDIFF(day, #tbl.date, tbl.Date) = 0

РЕДАКТИРОВАТЬ: Чтобы большинство комментариев и предлагаемых ответов имели смысл, оригиналвопрос был этот запрос:

DELETE FROM tbl
FROM tbl2

Ответы [ 2 ]

4 голосов
/ 05 июня 2019

Насколько я понимаю, вы бы использовали структуру , такую ​​как , здесь вы ограничиваете, какие строки удалять из первой таблицы на основе результатов запроса 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
2 голосов
/ 05 июня 2019

Я раньше такого не видел.Документация DELETE сообщает нам:

FROM table_source Указывает дополнительное предложение FROM.Это расширение Transact-SQL для DELETE позволяет указывать данные и удалять соответствующие строки из таблицы в первом предложении FROM.

Это расширение, задающее соединение, может использоваться вместо подзапроса в предложении WHERE дляопределить строки, которые нужно удалить.

Позже в том же документе мы находим

D.Использование соединений и подзапросов к данным в одной таблице для удаления строк в другой таблице В следующих примерах показаны два способа удаления строк в одной таблице на основе данных в другой таблице.В обоих примерах строки из таблицы SalesPersonQuotaHistory в базе данных AdventureWorks2012 удаляются на основе продаж за текущий год, хранящихся в таблице 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;  

Итак, у меня сложилось впечатление, что единственной причиной этого было использование имени реальной таблицы в качестве цели УДАЛИТЬ вместо псевдонима.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...