在MySQL中使用Join进行删除

CREATE TABLE `clients` ( `client_id` int(11), PRIMARY KEY (`client_id`) ); CREATE TABLE `projects` ( `project_id` int(11) unsigned, `client_id` int(11) unsigned, PRIMARY KEY (`project_id`) ); CREATE TABLE `posts` ( `post_id` int(11) unsigned, `project_id` int(11) unsigned, PRIMARY KEY (`post_id`) ); 

在我的PHP代码中,删除客户端时,我想删除所有项目的帖子:

 DELETE FROM posts INNER JOIN projects ON projects.project_id = posts.project_id WHERE projects.client_id = :client_id; 

posts表没有外键client_id ,只有project_id 。 我想删除发布在具有传递的client_id项目中的帖子。

这不是正在工作(没有职位被删除)。

你只需要指定你想从posts表中删除条目:

 DELETE posts FROM posts INNER JOIN projects ON projects.project_id = posts.project_id WHERE projects.client_id = :client_id 

编辑:欲了解更多信息,你可以看到这个替代答案

或者同样的事情,稍微不同的(IMO友好的)语法:

 DELETE FROM posts USING posts, projects WHERE projects.project_id = posts.project_id AND projects.client_id = :client_id; 

顺便说一句,使用连接的mysql几乎总是比子查询更快的方式…

由于您正在选择多个表,因此从中删除的表不再是明确的。 您需要选择

 delete posts from posts inner join projects on projects.project_id = posts.project_id where projects.client_id = :client_id 

在这种情况下, table_name1table_name2是相同的表,所以这将工作:

 delete projects from posts inner join [...] 

如果您想要,您甚至可以从两个表中删除:

 delete posts, projects from posts inner join [...] 

请注意, order bylimit 不适用于多表删除 。

另请注意,如果您为表格声明别名,则在引用表格时必须使用别名:

 delete p from posts as p inner join [...] 

来自Carpetsmoker等的贡献 。

你也可以像这样使用ALIAS,它只用于我的数据库! t是需要删除的表!

 DELETE t FROM posts t INNER JOIN projects p ON t.project_id = p.project_id AND t.client_id = p.client_id 

我更习惯于这个子查询解决方案,但我没有在MySQL中尝试过:

 DELETE FROM posts WHERE project_id IN ( SELECT project_id FROM projects WHERE client_id = :client_id ); 

MySQL DELETE使用JOIN记录

您通常在SELECT语句中使用INNER JOIN从其他表中具有相应记录的表中选择记录。 我们也可以使用DELETE语句中的INNER JOIN子句从表中删除记录,也可以删除其他表中的相应记录,例如,从满足特定条件的T1和T2表中删除记录,可以使用以下语句:

 DELETE T1, T2 FROM T1 INNER JOIN T2 ON T1.key = T2.key WHERE condition 

请注意,您在DELETE和FROM之间放置了表名T1和T2。 如果省略T1表,则DELETE语句只删除T2表中的记录,如果省略T2表,则只删除T1表中的记录。

连接条件T1.key = T2.key指定T2表中需要删除的相应记录。

WHERE子句中的条件指定需要删除T1和T2中的哪些记录。

尝试如下:

 DELETE posts.*,projects.* FROM posts INNER JOIN projects ON projects.project_id = posts.project_id WHERE projects.client_id = :client_id; 

单表删除:

为了从posts表中删除条目:

 DELETE ps FROM clients C INNER JOIN projects pj ON C.client_id = pj.client_id INNER JOIN posts ps ON pj.project_id = ps.project_id WHERE C.client_id = :client_id; 

为了从projects表中删除条目:

 DELETE pj FROM clients C INNER JOIN projects pj ON C.client_id = pj.client_id INNER JOIN posts ps ON pj.project_id = ps.project_id WHERE C.client_id = :client_id; 

为了从clients表中删除条目:

 DELETE C FROM clients C INNER JOIN projects pj ON C.client_id = pj.client_id INNER JOIN posts ps ON pj.project_id = ps.project_id WHERE C.client_id = :client_id; 

多个表删除:

为了从连接的结果中删除多个表中的条目,需要在DELETE之后指定表名作为逗号分隔的列表:

假设你想从一个特定客户端的所有三个表( postsprojectsclients )中删除条目:

 DELETE C,pj,ps FROM clients C INNER JOIN projects pj ON C.client_id = pj.client_id INNER JOIN posts ps ON pj.project_id = ps.project_id WHERE C.client_id = :client_id 
 mysql> INSERT INTO tb1 VALUES(1,1),(2,2),(3,3),(6,60),(7,70),(8,80); mysql> INSERT INTO tb2 VALUES(1,1),(2,2),(3,3),(4,40),(5,50),(9,90); 

从一个表中删除记录:

 mysql> DELETE tb1 FROM tb1,tb2 WHERE tb1.id= tb2.id; 

从两个表中删除记录:

 mysql> DELETE tb2,tb1 FROM tb2 JOIN tb1 USING(id); 

另一种使用子选择删除比使用IN更好的方法是WHERE EXISTS

 DELETE FROM posts WHERE EXISTS ( SELECT 1 FROM projects WHERE projects.client_id = posts.client_id); 

使用这个而不是连接的一个原因是DELETEJOIN禁止使用LIMIT 。 如果您希望在块中删除以免产生完整的表锁,可以使用DELETE WHERE EXISTS方法添加LIMIT

如果加入不适合你,你可以试试这个解决方案。 它用于删除t1时不使用外键+特定条件的孤立记录。 即它从table1中删除记录,这些记录具有空的“代码”字段,并且在table2中没有记录,通过字段“name”进行匹配。

 delete table1 from table1 t1 where t1.code = '' and 0=(select count(t2.name) from table2 t2 where t2.name=t1.name); 

尝试这个,

 DELETE posts.* FROM posts INNER JOIN projects ON projects.project_id = posts.project_id WHERE projects.client_id = :client_id 

– 请注意,您不能在需要删除的表上使用别名

 DELETE tbl_pagos_activos_usuario FROM tbl_pagos_activos_usuario, tbl_usuarios b, tbl_facturas c Where tbl_pagos_activos_usuario.usuario=b.cedula and tbl_pagos_activos_usuario.cod=c.cod and tbl_pagos_activos_usuario.rif=c.identificador and tbl_pagos_activos_usuario.usuario=c.pay_for and tbl_pagos_activos_usuario.nconfppto=c.nconfppto and NOT ISNULL(tbl_pagos_activos_usuario.nconfppto) and c.estatus=50