Как удалить из нескольких таблиц с помощью INNER JOIN на SQL-сервере

В MySQL вы можете использовать синтаксис

DELETE t1,t2 
FROM table1 AS t1 
INNER JOIN table2 t2 ...
INNER JOIN table3 t3 ...

Как мне сделать то же самое в SQL Server?

Ответ 1

В этом примере вы можете воспользоваться "удаленной" псевдо-таблицей. Что-то вроде:

begin transaction;

   declare @deletedIds table ( id int );

   delete from t1
   output deleted.id into @deletedIds
   from table1 as t1
    inner join table2 as t2
      on t2.id = t1.id
    inner join table3 as t3
      on t3.id = t2.id;

   delete from t2
   from table2 as t2
    inner join @deletedIds as d
      on d.id = t2.id;

   delete from t3
   from table3 as t3 ...

commit transaction;

Очевидно, вы можете сделать "вывод удален". на втором также удалите, если вам нужно что-то присоединиться к третьей таблице.

В качестве примечания вы также можете вставить. * В оператор вставки, а также вставить. * И удалить. * В оператор обновления.

РЕДАКТИРОВАТЬ: Кроме того, вы рассматривали возможность добавления триггера в таблице 1 для удаления из таблицы 2 + 3? Вы будете внутри неявной транзакции, а также будете иметь "вставлено". и "удалено". псевдостолы доступны.

Ответ 2

  • Вы всегда можете настроить каскадные удаления в отношениях между таблицами.

  • Вы можете инкапсулировать несколько удалений в одной хранимой процедуре.

  • Вы можете использовать транзакцию для обеспечения одной единицы работы.

Ответ 3

Вы можете использовать синтаксис JOIN в предложении FROM в DELETE в SQL Server, но вы все равно удаляете только из первой таблицы и ее собственное расширение Transact-SQL, которое является альтернативой подзапросу.

Из примера здесь:

 -- Transact-SQL extension
 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;

Ответ 4

Пример для удаления некоторых записей из главной таблицы и соответствующих записей из двух подробных таблиц:

BEGIN TRAN

  -- create temporary table for deleted IDs
  CREATE TABLE #DeleteIds (
    Id INT NOT NULL PRIMARY KEY
  )

  -- save IDs of master table records (you want to delete) to temporary table    
  INSERT INTO #DeleteIds(Id)
  SELECT DISTINCT mt.MasterTableId
  FROM MasterTable mt 
  INNER JOIN ... 
  WHERE ...  

  -- delete from first detail table using join syntax
  DELETE d
  FROM DetailTable_1 D
  INNER JOIN #DeleteIds X
    ON D.MasterTableId = X.Id


  -- delete from second detail table using IN clause  
  DELETE FROM DetailTable_2
  WHERE MasterTableId IN (
    SELECT X.Id
    FROM #DeleteIds X
  )


  -- and finally delete from master table
  DELETE d
  FROM MasterTable D
  INNER JOIN #DeleteIds X
    ON D.MasterTableId = X.Id

  -- do not forget to drop the temp table
  DROP TABLE #DeleteIds

COMMIT

Ответ 5

Просто интересно... это действительно возможно в MySQL? он удалит t1 и t2? или я просто неправильно понял вопрос.

Но если вы просто хотите удалить таблицу1 с несколькими условиями соединения, просто не используйте псевдоним таблицы, которую вы хотите удалить

DELETE t1,t2 
FROM table1 AS t1 
INNER JOIN table2 t2 ...
INNER JOIN table3 t3 ...

должен быть написан так, чтобы работать в MSSQL:

DELETE table1
FROM table1 
INNER JOIN table2 t2 ...
INNER JOIN table3 t3 ...

чтобы сравнить, как две другие общие СУБД выполняют операцию удаления:

http://mssql-to-postgresql.blogspot.com/2007/12/deleting-duplicates-in-postgresql-ms.html

Ответ 6

В принципе, вам не нужно делать три операции удаления в транзакции, сначала дети, а потом родители. Настройка каскадных удалений - хорошая идея, если это не одноразовая вещь, и ее существование не будет конфликтовать с существующей настройкой триггера.

Ответ 7

В SQL-сервере нет способа удалить несколько таблиц с помощью join. Поэтому сначала вы должны удалить его из родителя, прежде чем удалить родительский элемент формы.

Ответ 8

Все было указано. Просто используйте либо DELETE ON CASCADE в родительском table, либо удалите из child-table в parent.

Ответ 9

Это альтернативный способ удаления записей без оставления сирот.

Declare @user Table(keyValue int  , someString varchar(10))
insert into @user
values(1,'1 value')

insert into @user
values(2,'2 value')

insert into @user
values(3,'3 value')

Declare @password Table(  keyValue int , details varchar(10))
insert into @password
values(1,'1 Password')
insert into @password
values(2,'2 Password')
insert into @password
values(3,'3 Password')

        --before deletion
  select * from @password a inner join @user b
                on a.keyvalue = b.keyvalue
  select * into #deletedID from @user where keyvalue=1 -- this works like the output example
  delete  @user where keyvalue =1
  delete @password where keyvalue in (select keyvalue from #deletedid)

  --After deletion--
  select * from @password a inner join @user b
                on a.keyvalue = b.keyvalue

Ответ 10

Как уже указывал Aaron, вы можете установить поведение удаления в CASCADE и удалить записи детей, когда родительская запись будет удалена. Если вы не хотите, чтобы какая-то другая магия случилась (в этом случае были бы полезны пункты 2, 3 ответа Аарона), я не понимаю, почему вам нужно удалить с помощью внутренних соединений.

Ответ 11

Чтобы построить ответ Джона Гибба, для удаления набора данных в двух таблицах с отношением FK:

--*** To delete from tblMain which JOINs to (has a FK of) tblReferredTo PK  
--       i.e.  ON tblMain.Refer_FK = tblReferredTo.ID
--*** !!! If you're CERTAIN that no other rows anywhere also refer to the 
--      specific rows in tblReferredTo !!!
BEGIN TRAN;

    --*** Keep the ID from tblReferredTo when we DELETE from tblMain
    DECLARE @tblDeletedRefs TABLE ( ID INT );
    --*** DELETE from the referring table first
    DELETE FROM tblMain 
    OUTPUT DELETED.Refer_FK INTO @tblDeletedRefs  -- doesn't matter that this isn't DISTINCT, the following DELETE still works.
    WHERE ..... -- be careful if filtering, what if other rows 
                --   in tblMain (or elsewhere) also point to the tblReferredTo rows?

    --*** Now we can remove the referred to rows, even though tblMain no longer refers to them.
    DELETE tblReferredTo
    FROM   tblReferredTo INNER JOIN @tblDeletedRefs Removed  
            ON tblReferredTo.ID = Removed.ID;

COMMIT TRAN;

Ответ 12

DELETE     TABLE1 LIN
FROM TABLE1 LIN
INNER JOIN TABLE2 LCS ON  CONDITION
WHERE CONDITION

Ответ 13

$sql = "УДАЛИТЬ ОТ basic_tbl, education_tbl, personal_tbl, address_tbl, department_tbl С ПОМОЩЬЮ basic_tbl education_tbl personal_tbl, address_tbl, department_tbl ГДЕ b_id= e_id= p_id= a_id= d_id= ' "$ ID." ' ";  $ Rs = ($ mysqli_query мошенники, $SQL);