94

MySQLでは、あなたは構文を使用することができます

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

SQL Serverでも同じことをすることができますか?

13 답변


100

この例では "削除された"疑似テーブルを利用できます。何かのようなもの:

begin transaction;

   declare @deletedIds table ( id int );

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

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

   delete t3
   from table3 t3 ...

commit transaction;

明らかにあなたは「削除された出力」をすることができます。 3番目のテーブルに参加するために何かが必要な場合は、2番目の削除でも同様です。

ちなみに、insertステートメントではinsert。*を、updateステートメントではinsert。*とdeleted。*の両方を実行することもできます。

編集:また、table2 + 3から削除するためにtable1にトリガーを追加することを検討しましたか?あなたは暗黙のトランザクションの中にいるでしょう、そしてまた「挿入される」でしょう。「」を削除しました。"疑似テーブルが利用可能です。


  • 内部結合を使用してこの余分なテキストをすべて通過するのではなく、table1からWHERE id = xを削除してから次のテーブルから削除するほうがよいでしょうか。基本的に、内部結合をスキップするには2つの単純なクエリが必要です。それともこの方法はより効率的ですか? - Colandus
  • それはあなたのwhere句がどれほど複雑であるかによると思います。複雑なものでは、一度しか起こらないのでこれはより良いでしょう。しかし、多くの行に影響を与える単純なwhere句の場合は、テーブル変数に多くのIDを保持する必要がないため、提案のほうが効率的です。 - John Gibb
  • @ JohnGibb、この回答はどのように機能しますか? MySQL開発者が理解できるように、この答えを説明できますか? - Pacerier
  • @Pacerier私はMySQLに精通していません。これは、最初の削除はtable1からの削除のみで、削除されたIDを変数に保存するという考え方です。次の2つのステートメントは、その変数を使用してtable2とtable 3から関連する行を削除する方法を示しています。 - John Gibb
  • @ JohnGibb、今さんのクリア。答えにそれを含めるべきです。 - Pacerier

14

  1. テーブルのリレーションシップに対してカスケード削除をいつでも設定できます。

  2. 複数の削除を1つのストアドプロシージャにカプセル化できます。

  3. 1つの作業単位を確保するためにトランザクションを使用できます。


  • joinステートメントで確実に削除することは可能ですが、一度に複数のテーブルから削除したいだけです。 - Byron Whitlock
  • 間違った答え、joinはdeleteと一緒に使うことができます - rboarman
  • 答えは今正しいです。 - Robino
  • 広告1)それは本当ではない、それは常に可能ではないかもしれません。カスケード削除を設定できないシナリオがいくつかあります。サイクルまたは複数のカスケードパス。 (見るstackoverflow.com/a/3548225/108374例えば) - Tom Pažourek

14

SQL Serverでは、DELETEのFROM句にJOIN構文を使用できますが、それでも最初のテーブルからのみ削除するので、サブクエリに代わる独自の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;


  • 例D:Sales.SalesPersonQuotaHistoryからSales.SalesPersonQuotaHistoryを削除します。AS spqh内部結合Sales.SalesPerson AS sp spqh.BusinessEntityID = sp.BusinessEntityID WHERE sp.SalesYTD> 2500000.00; - Mark A

11

マスター表からいくつかのレコードを削除し、2つの詳細表から対応するレコードを削除する例

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


  • ご利用いただけますかSELECT INTO #DeleteIdsの代わりにCREATE TABLE 'DeleteIdsに続くINSERT INTO 'DeleteIds...? - Caltor

9

ちょっと不思議に思っています..それはMySQLで本当に可能ですか?それはT1とT2を削除しますか?あるいは私はただその質問を誤解しました。

ただし、複数の結合条件を指定してtable1を削除するだけの場合は、削除するテーブルに別名を付けないでください。

この:

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 ...

他の2つの一般的なRDBMSがどのように削除操作を行うのかを対比するために、

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


  • そこにあるSQL Serverの助言をありがとう、私はそれらの線に沿ってSQLを微調整しなければならなかった。 - Pauk

7

基本的に、トランザクションで3つのdeleteステートメントを作成する必要はありません。最初に子、次に親です。これが一回限りではなく、その存在が既存のトリガー設定と競合しない場合は、カスケード削除を設定することをお勧めします。


  • 関係が親子ではないので、一時テーブルにIDを選択する必要はないと思います。あるテーブルの行が削除されると、他の行を取得する方法はありません。 - Byron Whitlock

3

SQL Serverでは、joinを使って複数のテーブルを削除することはできません。 したがって、フォームの親を削除する前に、まず子から削除する必要があります。


2

これは孤児を離れることなくレコードを削除する別の方法です。


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


2

すべて指摘されています。どちらかを使うだけDELETE ON CASCADE親にtableまたはから削除child-tableparent


1

Aaronがすでに指摘したように、削除動作をCASCADEに設定することができ、それは親レコードが削除されたときに子レコードを削除します。あなたが他の種類の魔法を起こさせたくなければ(その場合Aaronの返答のポイント2、3が役に立つでしょう)、私はなぜあなたが内部結合で削除する必要があるのかわかりません。


0

FK関係を持つ2つのテーブル内のデータセットを削除するための、John Gibbの回答を基にします。

--*** To delete from tblMain which JOINs to (has a FK of) tblReferredTo's 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's 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;


-3

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


  • Nooooo ...それはうまくいかないでしょう。 - LittleBobbyTables
  • 複数のテーブルから削除されることはありません。質問をご理解ください - Kamran Shahid

-4

$ sql = "から削除basic_tbleducation_tblpersonal_tbladdress_tbldepartment_tbl使用中basic_tbleducation_tblpersonal_tbladdress_tbldepartment_tblどこにb_id=e_id=p_id=a_id=d_id= '"。$ id。"' ";  $ rs = mysqli_query($ con、$ sql);


  • フォーマットを修正して、コードが機能する理由を簡単に説明してください。 - Tanis.7x
  • SQLServerはmysqlではありません。それはMySQLでそのように動作します。 - Byron Whitlock

リンクされた質問


関連する質問

最近の質問