删除加入MySQL

Delete with Join in MySQL

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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代码中,删除客户机时,我希望删除所有项目日志:

1
2
3
4
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表中删除条目:

1
2
3
4
DELETE posts
FROM posts
INNER JOIN projects ON projects.project_id = posts.project_id
WHERE projects.client_id = :client_id

编辑:有关详细信息,您可以查看此备选答案


因为您选择了多个表,所以要从中删除的表不再是明确的。您需要选择:

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

在这种情况下,table_name1table_name2是相同的表,因此这将起作用:

1
DELETE projects FROM posts INNER JOIN [...]

如果您想:

1
DELETE posts, projects FROM posts INNER JOIN [...]

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

还要注意,如果为表声明别名,则在引用表时必须使用别名:

1
DELETE p FROM posts as p INNER JOIN [...]

地毯吸烟者等的贡献。


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

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

顺便说一下,使用mysql时,使用join的速度几乎总是比子查询快…


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

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


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

1
2
3
4
5
6
DELETE  FROM posts
WHERE   project_id IN (
            SELECT  project_id
            FROM    projects
            WHERE   client_id = :client_id
        );


mysql删除带join的记录

通常,在select语句中使用inner join从其他表中具有相应记录的表中选择记录。我们还可以将inner join子句与delete语句一起使用,从表中删除记录,以及其他表中的相应记录,例如,要从满足特定条件的T1和T2表中删除记录,可以使用以下语句:

1
2
3
4
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中的哪些记录。


单表删除:

为了从posts表中删除条目:

1
2
3
4
5
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表中删除条目:

1
2
3
4
5
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表中删除条目:

1
2
3
4
5
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中的条目:

1
2
3
4
5
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

尝试如下操作:

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


1
2
3
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);

从一个表中删除记录:

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

从两个表中删除记录:

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


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

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

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


如果join不适用于您,您可以尝试此解决方案。它用于在不使用外键+特定的where条件时从T1中删除孤立记录。即从表1中删除具有空字段"代码"且表2中没有记录的记录,并按字段"名称"匹配。

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


试试这个,

1
2
3
4
DELETE posts.*
FROM posts
INNER JOIN projects ON projects.project_id = posts.project_id
WHERE projects.client_id = :client_id


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

1
2
3
4
5
6
7
8
9
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