하나의 쿼리로 두 테이블에서 삭제


82

MySQL에 두 개의 테이블이 있습니다.

#messages table  : 
messageid
messagetitle 
.
.

#usersmessages table 
usersmessageid 
messageid
userid
.
.

이제 메시지 테이블에서 삭제하려면 괜찮습니다. 그러나 messageid로 메시지를 삭제할 때 레코드는 usersmessage에 여전히 존재하며이 두 테이블에서 한 번에 삭제해야합니다.

다음 쿼리를 사용했습니다.

DELETE FROM messages LEFT JOIN usersmessages USING(messageid) WHERE messageid='1' ; 

그런 다음 테스트

   DELETE FROM messages , usersmessages 
   WHERE messages.messageid = usersmessages.messageid 
   and messageid='1' ; 

그러나이 두 쿼리는이 작업을 수행하지 않습니다.

답변:


135

세미콜론으로 구분할 수 없습니까?

Delete from messages where messageid = '1';
Delete from usersmessages where messageid = '1'

또는

INNER JOIN아래와 같이 사용하십시오.

DELETE messages , usersmessages  FROM messages  INNER JOIN usersmessages  
WHERE messages.messageid= usersmessages.messageid and messages.messageid = '1'

1
이 코드를 루프에 넣으려면 어떻게됩니까? 나는 세미콜론을 절대적으로 넣을 수 있다는 것을 안다.
mehdi 2009-08-05

1
루프에 넣을 수 있습니다. 프로그래밍 방식으로 수행하고 메시지 ID를 매개 변수로 보낼 수 있습니다. 동일한 ID를 계속 보내지 않는 한 반복해서 삭제하지 않습니다.
Eric

4
이 작업을 두 개의 쿼리로 수행하면 실제로 트랜잭션으로 래핑해야합니다. 루프에서 삭제 쿼리를 실행하는 경우 모든 삭제를 수행하는 단일 쿼리를 공식화하는 것이 좋습니다.
JohnFx

1
조인을 사용하여 삭제 쿼리의 또 다른 예를 확인하십시오. bennadel.com/blog/…
Babar

19
SQL Server에서 작동하지 않음 : ','근처에 잘못된 구문이 있습니다.
Paul-Sebastian Manole

44
DELETE a.*, b.* 
FROM messages a 
LEFT JOIN usersmessages b 
ON b.messageid = a.messageid 
WHERE a.messageid = 1

번역 : 테이블에서 삭제 된 메시지 테이블 경우의 MessageID = 1, uersmessages가 의 MessageID =의 MessageID 테이블의이 메시지 의 해당 행 삭제 uersmessages의 테이블을.


모두에 대한 주석 :이 예제에 표시된 것처럼 삭제가 작동해야하는 테이블을 지정하는 것이 중요합니다. 위대한 포스트 @angry_kiwi
Raphael_b

LEFT 메시지에게 가입 b를 나는 usersmessages로부터 단지 순서를 변경했다
파블로

15

당신이 중 하나를 만들어야 FOREIGN KEYON DELETE CASCADE:

ALTER TABLE usersmessages
ADD CONSTRAINT fk_usermessages_messageid
FOREIGN KEY (messageid)
REFERENCES messages (messageid)
ON DELETE CASCADE

, 또는 트랜잭션에서 두 개의 쿼리를 사용하여 수행하십시오.

START TRANSACTION;;

DELETE
FROM    usermessages
WHERE   messageid = 1

DELETE
FROM    messages
WHERE   messageid = 1;

COMMIT;

InnoDB하지만 트랜잭션은 테이블 에만 영향을 미칩니다 .


3
하나의 쿼리로 여러 테이블에서 삭제할 수 있습니다 ! dev.mysql.com/doc/refman/5.0/en/delete.html
txwikinger

그래 넌 할수있어! 그러나 나에게는 ... 내 대답이 말한 것을하는 것이 더 쉽습니다.
Eric

비슷한 테이블에 캐스케이드를 추가했습니다. 하나의 테이블에서만 삭제를 시도했을 때 레코드를 삭제하고 관련 레코드를 고아로 두었습니다. 제약은 무엇입니까?
barfoon

@barfoon : 테이블이 InnoDB있습니까?
Quassnoi

@Quassnoi 죄송합니다! 나는 그것이 얼마나 어리석은 일이라고 생각했습니다. 모든 테이블은 MyISAM입니다. 데이터가 포함 된 모든 항목을 즉시 변경할 수 있습니까? 아니면 문제가 있습니까?
barfoon

7

두 가지 옵션이 있습니다.

먼저 트랜잭션 내에서 두 개의 문을 수행합니다.

BEGIN;
  DELETE FROM messages WHERE messageid = 1;
  DELETE FROM usermessages WHERE messageid = 1;
COMMIT;

또는 외래 키로 ON DELETE CASCADE를 설정할 수 있습니다. 이것이 더 나은 접근 방식입니다.

CREATE TABLE parent (
  id INT NOT NULL,
    PRIMARY KEY (id)
);

CREATE TABLE child (
  id INT, parent_id INT,
  FOREIGN KEY (parent_id) REFERENCES parent(id) ON DELETE CASCADE
);

ON DELETE CASCADE에 대한 자세한 내용은 여기에서 확인할 수 있습니다 .


7

JOINS 필요 없음 :

DELETE m, um FROM messages m, usersmessages um

WHERE m.messageid = 1 

AND m.messageid = um.messageid 

6
DELETE message.*, usersmessage.* from users, usersmessage WHERE message.messageid=usersmessage.messageid AND message.messageid='1'

6

OP는 삭제 후 테이블 별칭이 누락되었습니다.

DELETE t1, t2 
FROM table1 t1 LEFT JOIN table2 t2 ON t1.id = t2.id 
WHERE t1.id = some_id

3
답변 해 주셔서 감사합니다. 이것이 작동하는 이유와 OP 솔루션이 작동하지 않는 이유를 설명하려고하면 더 도움이 될 것입니다.
DdW

1

이것을 시도하십시오

DELETE FROM messages,usersmessages

USING messages

INNER JOIN usermessages on (messages.messageid = usersmessages.messageid)

WHERE messages.messsageid='1'

0

이 시도..

DELETE a.*, b.*  
FROM table1 as a, table2 as b  
WHERE a.id=[Your value here] and b.id=[Your value here]

id샘플 칼럼으로 하겠습니다 .

도움이되어 기쁩니다. :)


별표 ( *)가 제대로 렌더링 되려면 앞에 공백이 4 개있는 쿼리를 들여 쓰기해야합니다.
Al.G.

0

두 열에 동일한 열 이름이 2 개 이상있을 때 특정 값을 삭제하려면 이와 같이 사용할 수도 있습니다.

DELETE project , create_test  FROM project INNER JOIN create_test
WHERE project.project_name='Trail' and  create_test.project_name ='Trail' and project.uid= create_test.uid = '1';

0

여기에 언급되지 않은 또 다른 방법이 있습니다 (아직 성능을 완전히 테스트하지 않았습니다), 모든 테이블에 대해 배열을 설정할 수 있습니다-> 삭제하려는 행을 아래와 같이 설정할 수 있습니다

// set your tables array
$array = ['table1', 'table2', 'table3'];


// loop through each table
for($i = 0; $i < count($array); $i++){

 // get each single array
 $single_array = $array[$i];

 // build your query
 $query = "DELETE FROM $single_array WHERE id = 'id'";

 // prepare the query and get the connection
 $data = con::GetCon()->prepare($query);

 // execute the action
 $data->execute();
}

그런 다음 사용자를 홈 페이지로 리디렉션 할 수 있습니다.

header('LOCATION:' . $home_page);

이것이 누군가를 도울 수 있기를 바랍니다 :)

감사


이것은 누군가에게 도움이 될 수 있습니다 ... PHP처럼 보이지만 반드시 질문의 범위 내에 있다고 생각하지 않습니다. :)
Tom Bush
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.