MySQL의 여러 테이블에서 삭제하는 방법은 무엇입니까?


116

한 번에 몇 개의 테이블에서 삭제하려고합니다. 나는 약간의 조사를했고, 이것을 생각 해냈다

DELETE FROM `pets` p,
            `pets_activities` pa
      WHERE p.`order` > :order
        AND p.`pet_id` = :pet_id
        AND pa.`id` = p.`pet_id`

그러나이 오류가 발생합니다.

Uncaught Database_Exception [1064] : SQL 구문에 오류가 있습니다. 'p, pets_activitiespa ... 근처에서 사용할 올바른 구문은 MySQL 서버 버전에 해당하는 설명서를 확인하십시오 .

나는 전에 크로스 테이블 삭제를 한 적이 없기 때문에 경험이없고 지금은 붙어 있습니다!

내가 뭘 잘못하고 있죠?

답변:


204

JOIN에서 사용하십시오 DELETE.

DELETE p, pa
      FROM pets p
      JOIN pets_activities pa ON pa.id = p.pet_id
     WHERE p.order > :order
       AND p.pet_id = :pet_id

또는 사용할 수 있습니다 ...

DELETE pa
      FROM pets_activities pa
      JOIN pets p ON pa.id = p.pet_id
 WHERE p.order > :order
   AND p.pet_id = :pet_id

...에서만 삭제 pets_activities

참조 .

단일 테이블 삭제를 들어, 아직 참조 무결성과 함께, 서로 수행하는 방법이 있습니다 EXISTS, NOT EXISTS, IN, NOT IN등 그러나 전에 별칭으로 삭제하는있는 테이블에서 지정하는 위 한 FROM절은 몇 꽤 꽉 당신을 얻을 수는 더 쉽게 반점. 나는 EXISTS99 %의 경우에 손을 뻗는 경향이 있으며 ,이 MySQL 구문이 하루에 걸리는 1 %가 있습니다.


7
6 개의 큰 테이블 (약 15k 행)을 결합하여이 "1 쿼리에서 모두 삭제"를 시도했으며 쿼리는 6 개의 테이블에서 63 개의 행을 삭제하는 데 155 초가 걸렸습니다. O
Klemen Tušar

1
@cadman 이것이 진짜 정답입니다. 이 그것을 사용에 대한 인수 할 수 있지만, 경우에 매우 유용 할 수 있습니다
사이먼 기독교

1
+1 질문이 "당신이해야 하는가"가 아니라 "방법"이었기 때문에 나는 이것이 진짜 정답에 동의합니다. 그러나 1 %에 대해 듣고 싶습니다. 이것이 선호되는 단일 상황을 생각할 수 없기 때문입니다.
Erick Robertson

2
@techouse, 인덱스에 가입하고 필터링 했습니까? 15k x 15k x 15k x 15k 15k x 15k는 1100 만입니다. SELECT비슷하게 오래 걸렸 나요 ?
Paul Draper

6
두 번째 테이블에 일치하는 항목이없는 경우 유용한 LEFT JOIN을 사용할 수도 있습니다. 그렇지 않으면 아무것도 삭제되지 않습니다.
Lexib0y 2015

20

이 사이에 간단한 부모 / 자식 관계로 보이므로 petspets_activities , 당신은 더 나은 삭제 캐스케이드와 외래 키 제약 조건을 만들 해제 될 것입니다.

이렇게하면 pets행이 삭제 될 때pets_activities 연관된 행도 자동으로 삭제됩니다.

그러면 쿼리가 간단 해집니다.

delete from `pets`
    where `order` > :order
      and `pet_id` = :pet_id

3
@Erick, 참조 무결성을 설정 한 경우 계단식 삭제는 자체적으로 삭제하는 것보다 더 많은 문제를 일으킬 수 없습니다. 우리는 이미 매핑 으로 인해 pa적절한 자식 임을 알고 있습니다. pid/pet_id
paxdiablo

14
글쎄, 너희들은 자신의 생각을 가지고 있지만 DBMS의 힘을 많이 할인하고있는 것 같습니다. 계단식 삭제는 트리거, 저장 프로 시저 또는 제약 조건만큼이나 데이터 관리의 일부이며 수행중인 작업을 모르는 경우에만 위험합니다. 그래도 요점을 더 이상 주장하지 않을 것입니다. 우리는 동의하지 않는 것에 동의해야합니다.
paxdiablo

8
에릭, 이제 당신은 내 관심을 불러 일으켰습니다. 제약없이 데이터베이스 내에서 데이터 무결성을 어떻게 보장합니까?
paxdiablo

4
@Erick은 "또한 트리거, 저장 프로 시저 또는 제약 조건을 사용하지 않습니다."라고 말했습니다. 아, Excel을 사용합니다. :-)
james.garriss 2013-08-24

4
나는 이것에 대해 후속 조치를 취하고 싶습니다. 이 상황에서 캐스케이드 삭제에 대한 내 입장을 변경했습니다. 나는 그들을 사용하고 잘 사용하는 새로운 SQL 환경의 일부였으며 매우 체계적으로 구성되었습니다. 이 시스템에서는 이러한 캐스케이드를 제자리에 두는 것이 우리에게 매우 유리했습니다. 고아 데이터를 확실히 방지하고 위험하지 않았습니다. 문제는 데이터베이스를 사용하는 모든 사람이 데이터베이스를 안전하게 사용하는 방법을 이해해야한다는 것입니다. 그러나 주니어 개발자가 감독없이 데이터베이스를 변경할 때 항상 위험이 따릅니다.
Erick Robertson


3

현재 테스트 할 mysql 데이터베이스가 없지만 from 절 이전에 삭제할 항목을 지정해 보셨습니까? 예를 들면 :

DELETE p, pa FROM `pets` p,
        `pets_activities` pa
  WHERE p.`order` > :order
    AND p.`pet_id` = :pet_id
    AND pa.`id` = p.`pet_id`

사용한 구문은 최신 버전의 mysql로 ​​제한되어 있다고 생각합니다.


1
이 쿼리는 성공적으로 실행되었지만 행을 삭제하지 않았습니다 (하지만 있어야한다고 생각합니다).
alex

2

구문이 나에게 맞는 것 같습니다 ... 사용하도록 변경하십시오 INNER JOIN...

이것 좀 봐 .


7
링크가 정확하기 때문에 실제 솔루션을 포함하지 않은 것이 아쉽습니다!
mycroes 2014 년

1

2017 년에이 글을 읽는 사람에게는 이것이 제가 비슷한 일을 한 방법입니다.

DELETE pets, pets_activities FROM pets inner join pets_activities
on pets_activities.id = pets.id WHERE pets.`order` > :order AND 
pets.`pet_id` = :pet_id

일반적으로 여러 테이블에서 행을 삭제하기 위해 따르는 구문은 다음과 같습니다. 솔루션은 두 테이블 사이에 어떤 관계가 있다는 가정을 기반으로합니다.

DELETE table1, table2 FROM table1 inner join table2 on table2.id = table1.id
WHERE [conditions]

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.