SQL Server에서 INNER JOIN을 사용하여 여러 테이블에서 삭제하는 방법


117

MySQL에서는 구문을 사용할 수 있습니다.

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

SQL Server에서 동일한 작업을 수행하려면 어떻게합니까?

답변:


119

이 예에서 "삭제 된"의사 테이블을 활용할 수 있습니다. 다음과 같은 것 :

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;

분명히 '출력 삭제'를 할 수 있습니다. 세 번째 테이블에 대한 조인이 필요한 경우 두 번째 삭제에서도 마찬가지입니다.

참고로 insert 문에 insert. *를 수행하고 update 문에 insert. * 및 deleted. *를 둘 다 수행 할 수도 있습니다.

편집 : 또한 table2 + 3에서 삭제하기 위해 table1에 트리거를 추가하는 것을 고려 했습니까? 당신은 암시 적 트랜잭션 내부에있을 것이고 "inserted. "와 "deleted. "가상 테이블도 사용할 수있을 것입니다.


2
내부 조인을 사용 하고이 추가 텍스트를 모두 통과하는 대신 table1 WHERE id = x에서 삭제 한 다음 다음 테이블에서 삭제하는 것이 더 낫습니까 ?? 기본적으로 내부 조인을 건너 뛰면 2 개의 간단한 쿼리가 필요합니다. 아니면이 방법이 더 효율적입니까?
Colandus 2013 년

where 절이 얼마나 복잡한 지에 달려 있다고 생각합니다. 복잡한 경우에는 한 번만 발생하기 때문에 더 좋습니다. 그러나 많은 행에 영향을 미치는 더 간단한 where 절의 경우 테이블 변수에 많은 ID를 보유 할 필요가 없기 때문에 제안이 더 효율적일 수 있습니다.
John Gibb

@ JohnGibb,이 답변은 어떻게 작동합니까? MySQL 개발자가 이해할 수 있도록이 답변을 설명 할 수 있습니까?
Pacerier 2015

@Pacerier 저는 MySQL에 익숙하지 않습니다. 첫 번째 삭제는 table1에서만 삭제되지만 삭제 된 ID를 변수에 저장하는 것입니다. 다음 두 문은 해당 변수를 사용하여 table2 및 table 3에서 연관된 행을 삭제하는 방법입니다.
John Gibb

@JohnGibb는 지금 그건 분명. 답변에 포함시켜야합니다.
Pacerier

15
  1. 항상 테이블 관계에 계단식 삭제를 설정할 수 있습니다.

  2. 하나의 저장 프로 시저에 여러 삭제를 캡슐화 할 수 있습니다.

  3. 트랜잭션을 사용하여 하나의 작업 단위를 보장 할 수 있습니다.


3
조 인문에서 확실히 삭제할 수 있지만 한 번에 둘 이상의 테이블에서 삭제하고 싶습니다.
Byron Whitlock

오답, 조인은 delete와 함께 사용할 수 있습니다.
rboarman 2010

ad 1.) 그것은 사실이 아니며 항상 가능한 것은 아닙니다. 순환 또는 다중 계단식 경로와 같이 계단식 삭제를 설정할 수없는 몇 가지 시나리오가 있습니다. ( 예를 들어 stackoverflow.com/a/3548225/108374 참조 )
Tom Pažourek

15

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;

3
예 D : Sales.SalesPersonQuotaHistory에서 Sales.SalesPersonQuotaHistory에서 spqh로 삭제 INNER JOIN Sales.SalesPerson AS sp에서 spqh.BusinessEntityID = sp.BusinessEntityID WHERE sp.SalesYTD> 2500000.00;
Mark A

11

마스터 테이블에서 일부 레코드를 삭제하고 두 세부 테이블에서 해당 레코드를 삭제하는 예 :

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

1
뒤에 오는 SELECT INTO #DeleteIds대신 사용할 수 있습니까? CREATE TABLE 'DeleteIdsINSERT 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 ...

다른 두 개의 일반적인 RDBMS가 삭제 작업을 수행하는 방법을 대조합니다.

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


SQL Server 팁을 주셔서 감사합니다. 그 라인을 따라 SQL을 수정해야했습니다.
Pauk

7

기본적으로 트랜잭션에서 세 개의 삭제 문을 만들 필요가 없습니다. 계단식 삭제를 설정하는 것은 이것이 일회용이 아니고 기존 트리거 설정과 충돌하지 않는 경우 좋은 생각입니다.


나는 그렇게 할 필요가 없기를 바라고 있었고, 관계가 부모 자식이 아니기 때문에 임시 테이블에서 ID를 선택해야한다고 가정합니다. 한 테이블의 행이 사라지면 다른 행을 가져올 방법이 없습니다.
Byron Whitlock

3

SQL Server에서는 조인을 사용하여 여러 테이블을 삭제할 수 없습니다. 따라서 부모 양식을 삭제하기 전에 먼저 자식에서 삭제해야합니다.


2

이것은 고아를 떠나지 않고 레코드를 삭제하는 또 다른 방법입니다.

@user Table (keyValue int, someString varchar (10)) 선언
@user에 삽입
값 (1, '1 값')

@user에 삽입
값 (2, '2 값')

@user에 삽입
값 (3, '3 값')

@password Table (keyValue int, 세부 사항 varchar (10)) 선언
@password에 삽입
values ​​(1, '1 비밀번호')
@password에 삽입
values ​​(2, '2 비밀번호')
@password에 삽입
values ​​(3, '3 비밀번호')

        -삭제 전
  @password에서 *를 선택하십시오.
                a.keyvalue = b.keyvalue
  select * into #deletedID from @user where keyvalue = 1-이것은 출력 예제처럼 작동합니다.
  키 값이 = 1 인 @user 삭제
  키 값이있는 @password 삭제 (#deletedid에서 키 값 선택)

  -삭제 후-
  @password에서 *를 선택하십시오.
                a.keyvalue = b.keyvalue


2

모든 것이 지적되었습니다. DELETE ON CASCADE부모 중 하나만 사용 하십시오.table 또는에서 삭제할 child-table받는 사람 parent.


자식 테이블에서 부모로 삭제한다는 것은 무엇을 의미합니까? 질문이나 앞서 언급 한 답변에서 보여준 것과 같은 조인 기술을 사용한다는 의미입니까?
Imran Faruqi

1

Aaron이 이미 지적했듯이 삭제 동작을 CASCADE로 설정할 수 있으며 상위 레코드가 삭제되면 하위 레코드가 삭제됩니다. 어떤 종류의 다른 마술이 일어나기를 원하지 않는 한 (Aron의 답변의 포인트 2, 3이 유용 할 것입니다) 왜 내부 조인으로 삭제 해야하는지 알 수 없습니다.


0

John Gibb의 답변을 기반으로 FK 관계가있는 두 테이블의 데이터 집합을 삭제하려면 다음을 수행하십시오.

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

2 개 이상의 table.Please에서 문제 것을 이해는 삭제되지 않습니다
캄란 샤 히드

-5

$ SQL = "에서 삭제 basic_tbl, education_tbl, personal_tbl, address_tbl,department_tbl 사용 basic_tbl, education_tbl, personal_tbl, address_tbl, department_tbl WHERE b_id= e_id= p_id= a_id= d_id= '"$ 아이디.. "'"; $ rs = mysqli_query ($ con, $ sql);


형식을 수정하고 코드가 작동하는 이유에 대한 간략한 설명을 제공하세요.
Bryan Herbst
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.