在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_name1
和table_name2
是相同的表,所以这将工作:
delete projects from posts inner join [...]
如果您想要,您甚至可以从两个表中删除:
delete posts, projects from posts inner join [...]
请注意, order by
和limit
不适用于多表删除 。
另请注意,如果您为表格声明别名,则在引用表格时必须使用别名:
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
之后指定表名作为逗号分隔的列表:
假设你想从一个特定客户端的所有三个表( posts
, projects
, clients
)中删除条目:
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);
使用这个而不是连接的一个原因是DELETE
和JOIN
禁止使用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