在MySQL中使用Join删除

下面是创建我的表的脚本:

CREATE TABLE clients (
client_i 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的项目中的帖子。

这是不工作的,因为没有帖子被删除。

378660 次浏览

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

DELETE  FROM posts
WHERE   project_id IN (
SELECT  project_id
FROM    projects
WHERE   client_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中使用连接几乎总是比子查询更快…

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

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

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

试试下面的方法:

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

如果join不适合你,你可以尝试这个解决方案。它用于在不使用外键+特定的where条件时从t1中删除孤立记录。也就是说,它从table1中删除有空字段“code”而在table2中没有记录的记录,通过字段“name”匹配。

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

你也可以像这样使用别名,它只是在我的数据库上使用它!T是需要删除的表!

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

由于您正在选择多个表,要删除的表不再是明确的。你需要选择:

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和etc的贡献

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

MySQL使用JOIN删除记录

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

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

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

连接条件T1。key = T2。key表示T2表中需要删除的对应记录。

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

试试这个,

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

单表删除:

为了从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

一种解决方案是使用子查询

DELETE FROM posts WHERE post_id in (SELECT post_id FROM posts p
INNER JOIN projects prj ON p.project_id = prj.project_id
INNER JOIN clients c on prj.client_id = c.client_id WHERE c.client_id = :client_id
);

子查询返回需要删除的ID;所有三个表都使用连接连接,只有那些符合过滤条件的记录被删除(在你的例子中,即where子句中的client_id)。