在一个查询中从两个表中删除


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' ; 

但是这两个查询不能完成此任务。

Answers:


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

1
它可以放在一个循环中。您可以通过编程方式进行操作,并将消息ID作为参数发送。只要您不继续发送相同的ID,就不会一遍又一遍地删除。
Eric

4
如果在两个查询中执行此操作,则实际上应该将其包装在事务中。至于在循环中运行删除查询,最好用一个查询来完成所有删除操作。
2009年


19
不适用于SQL Server:“,”附近的语法不正确。
Paul-Sebastian Manole 2015年

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

转换:从表message中删除messageid = 1的表,如果表uersmessages的messageid =表messagemessageid,则删除该uersmessages表的行。


对所有人发表评论:如本例所示,重要的是指定删除应在哪个表中进行。好帖子@angry_kiwi
Raphael_b 2015年

我只需要更改顺序,即FROM usersmessages b LEFT JOIN消息a
Pablo

15

您应该创建一个FOREIGN KEY具有ON 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

是的你可以!但是对我来说...按照我的回答说要容易些。
埃里克

我在我的类似表上添加了级联。当我尝试仅从1个表中删除时,它删除了记录并留下了相关的一个孤立记录。约束有什么用?
barfoon 2010年

@barfoon:是您的桌子InnoDB吗?
Quassnoi

@Quassnoi糟糕!我肯定以为是愚蠢的。所有表都是MyISAM。我是否可以使用其中的数据即时更改所有这些?还是有问题吗?
barfoon 2010年

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

无需加入:

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
感谢您的回答。如果您尝试解释为什么这样做会起作用,而OPs解决方案却不会起作用,那将会更有帮助。
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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.