从多个表中删除

时间:2014-07-15 13:30:51

标签: mysql sql

我有一张用户表 用户ID

3 ,Frank
4 ,Steve
5 ,Joe

和一个角色表,其中第1列是上表中用户的id:

1, billing
3, Admin
2, Admin
4, user
5, billing

正如您所见,用户1和2已成为孤儿,并且没有id为2的用户。如何从角色表中删除此条目?在没有用户的角色中可能有数十个条目。

这会有用吗?

 DELETE from roles,users where roles.userId!==users.userId

3 个答案:

答案 0 :(得分:1)

如果用户不在,则无需从users删除。所以你可以这样做:

delete r from roles r
    where not exists (select 1 from users u where u.userId = r.userId);

如评论中所述,如果您将roles.userId值声明为外键引用,则数据库不会发生这种情况。修复数据后,您可以执行以下操作:

alter table roles add constraint foreign key (userId) references user(userId);

答案 1 :(得分:1)

DELETE FROM roles WHERE id NOT IN (SELECT id FROM users)

答案 2 :(得分:0)

问:这会有效吗?

A:关闭,但没有雪茄。不,问题中的陈述不会执行指定的操作。

首先,编写一个查询来识别孤立的行。反连接模式是一种常见的方法(尽管还有其他几种可行的方法):

SELECT r.*
  FROM `roles` r
  LEFT
  JOIN `user` u 
    ON u.id = r.user_id
 WHERE u.id IS NULL    

这使用"外部" join,从roles返回所有行,以及来自user的匹配行。如果在user中找不到匹配的行,则user表中的列将返回NULL。给定连接谓词(ON子句)中的相等比较,我们知道所有匹配的行都具有u.id的非NULL值。 "技巧"是WHERE子句中的谓词,它排除了找到匹配项的所有行,因此我们在roles中留下了users

中没有匹配行的行

(如果您想检查将要删除的行和/或创建这些行的"备份"此查询会为您提供。)

接下来,将SELECT语句转换为DELETE语句。对于这个特殊的陈述,它对MySQL来说非常简单。唯一需要做的更改是使用SELECT关键字替换DELETE关键字:

DELETE r.*
  FROM `roles` r
  LEFT
  JOIN `user` u 
    ON u.id = r.user_id
 WHERE u.id IS NULL    

这只是几种可行方法之一的例子。