MySQL从数据库中选择不在

MySQL从数据库中选择不在,mysql,sql,join,Mysql,Sql,Join,如果在另一个数据库中不存在记录,我需要根据该数据库清理这些记录。 这很难解释,所以这里有一个例子: Table Users ----------- id username password Table Articles -------------- id title created_by edited_by created_by和deleted_by包含用户ID。 我有3-4个表,它们的结构与文章表几乎相同,我想从表中删除那些在文章表中没有任何记录的用户。 我的意思是在创建人和编辑人表格中的

如果在另一个数据库中不存在记录,我需要根据该数据库清理这些记录。
这很难解释,所以这里有一个例子:

Table Users
-----------
id
username
password

Table Articles
--------------
id
title
created_by
edited_by

created_by
deleted_by
包含用户ID。 我有3-4个表,它们的结构与文章表几乎相同,我想从表中删除那些在文章表中没有任何记录的用户。

我的意思是在
创建人
编辑人
表格中的
表格等文章中找不到ID的用户。
怎么做?
我首先尝试查看是否可以根据用户选择所有表的所有数据,但服务器无法执行查询:

SELECT * FROM `users` 
JOIN `articles` 
ON `articles`.`created_by` = `users`.`id`  
AND `articles`.`edited_by` = `users`.`id` 
JOIN `articles_two` 
ON `articles_two`.`created_by` = `users`.`id` 
AND `articles_two`.`edited_by` = `users`.`id` 
JOIN `articles_three` 
ON `articles_three`.`created_by` = `users`.`id` 
AND `articles_three`.`edited_by` = `users`.`id` 
JOIN `articles_four` 
ON `articles_four`.`created_by` = `users`.`id` 
AND `articles_four`.`edited_by` = `users`.`id` 
JOIN `articles_five` 
ON `articles_five`.`created_by` = `users`.`id` 
AND `articles_five`.`edited_by` = `users`.`id` 
JOIN `articles_six` 
ON `articles_six`.`created_by` = `users`.`id` 
AND `articles_six`.`edited_by` = `users`.`id`;

这应该行得通。它不是非常优雅,但我认为它很容易遵循:

DELETE FROM Users
WHERE ID NOT IN (
  SELECT Created_By FROM Articles
  UNION SELECT Edited_By FROM Articles
  UNION SELECT Created_By FROM Articles_Two
  UNION SELECT Edited_By FROM Articles_Two
  ...
  UNION SELECT Created_By FROM Articles_Six
  UNION SELECT Edited_By FROM Articles_Six
)

与任何大的“清理”查询一样,(a)首先复制一份表,(b)在键入
COMMIT

之前仔细检查,这应该是可行的。它不是非常优雅,但我认为它很容易遵循:

DELETE FROM Users
WHERE ID NOT IN (
  SELECT Created_By FROM Articles
  UNION SELECT Edited_By FROM Articles
  UNION SELECT Created_By FROM Articles_Two
  UNION SELECT Edited_By FROM Articles_Two
  ...
  UNION SELECT Created_By FROM Articles_Six
  UNION SELECT Edited_By FROM Articles_Six
)

与任何大型“清理”查询一样,(a)首先复制一份表,(b)在键入
COMMIT

之前仔细检查,我认为最干净的方法是
不在
选择
子句中:

select *
from users u
where u.id not in (select created_by from articles where created_by is not null) and
      u.id not in (select edited_by from articles where edited_by is not null) and
      u.id not in (select created_by from articles_two where created_by is not null) and
      u.id not in (select edited_by from articles_two where edited_by is not null) and
      u.id not in (select created_by from articles_three where created_by is not null) and
      u.id not in (select edited_by from articles_three where edited_by is not null) and
      u.id not in (select created_by from articles_four where created_by is not null) and
      u.id not in (select edited_by from articles_four where edited_by is not null)

在由
创建的和由
编辑的各个列上建立索引,应该有助于提高性能。

我认为最干净的方法是在
选择
子句中的
不在
中:

select *
from users u
where u.id not in (select created_by from articles where created_by is not null) and
      u.id not in (select edited_by from articles where edited_by is not null) and
      u.id not in (select created_by from articles_two where created_by is not null) and
      u.id not in (select edited_by from articles_two where edited_by is not null) and
      u.id not in (select created_by from articles_three where created_by is not null) and
      u.id not in (select edited_by from articles_three where edited_by is not null) and
      u.id not in (select created_by from articles_four where created_by is not null) and
      u.id not in (select edited_by from articles_four where edited_by is not null)

性能应该通过在由
创建的
和由
编辑的
列上建立索引来提高。

在MySQL中,
左外连接。。。如果null
往往比
中的
或存在的性能更好(如果有适当的索引),那么以下内容应该值得尝试:

SELECT u.* FROM `users` u
LEFT JOIN `articles` ac1 ON ac1.`created_by` = u.`id`  
LEFT JOIN `articles_two` ac2 ON ac2.`created_by` = u.`id` 
LEFT JOIN `articles_three` ac3 ON ac3.`created_by` = u.`id` 
LEFT JOIN `articles_four` ac4 ON ac4.`created_by` = u.`id` 
LEFT JOIN `articles_five` ac5 ON ac5.`created_by` = u.`id` 
LEFT JOIN `articles_six` ac6 ON ac6.`created_by` = u.`id` 
LEFT JOIN `articles` ae1 ON ae1.`edited_by` = u.`id` 
LEFT JOIN `articles_two` ae2 ON ae2.`edited_by` = u.`id` 
LEFT JOIN `articles_three` ae3 ON ae3.`edited_by` = u.`id` 
LEFT JOIN `articles_four` ae4 ON ae4.`edited_by` = u.`id` 
LEFT JOIN `articles_five` ae5 ON ae5.`edited_by` = u.`id` 
LEFT JOIN `articles_six` ae6 ON ae6.`edited_by` = u.`id`
WHERE COALESCE(ac1.`created_by`,ac2.`created_by`,ac3.`created_by`,
               ac4.`created_by`,ac5.`created_by`,ac6.`created_by`,
               ae1.`edited_by`, ae2.`edited_by`, ae3.`edited_by`, 
               ae4.`edited_by`, ae5.`edited_by`, ae6.`edited_by`)
IS NULL;

在MySQL中,
左外连接。。。如果null
往往比中的或存在的性能更好(如果有适当的索引),那么以下内容应该值得尝试:

SELECT u.* FROM `users` u
LEFT JOIN `articles` ac1 ON ac1.`created_by` = u.`id`  
LEFT JOIN `articles_two` ac2 ON ac2.`created_by` = u.`id` 
LEFT JOIN `articles_three` ac3 ON ac3.`created_by` = u.`id` 
LEFT JOIN `articles_four` ac4 ON ac4.`created_by` = u.`id` 
LEFT JOIN `articles_five` ac5 ON ac5.`created_by` = u.`id` 
LEFT JOIN `articles_six` ac6 ON ac6.`created_by` = u.`id` 
LEFT JOIN `articles` ae1 ON ae1.`edited_by` = u.`id` 
LEFT JOIN `articles_two` ae2 ON ae2.`edited_by` = u.`id` 
LEFT JOIN `articles_three` ae3 ON ae3.`edited_by` = u.`id` 
LEFT JOIN `articles_four` ae4 ON ae4.`edited_by` = u.`id` 
LEFT JOIN `articles_five` ae5 ON ae5.`edited_by` = u.`id` 
LEFT JOIN `articles_six` ae6 ON ae6.`edited_by` = u.`id`
WHERE COALESCE(ac1.`created_by`,ac2.`created_by`,ac3.`created_by`,
               ac4.`created_by`,ac5.`created_by`,ac6.`created_by`,
               ae1.`edited_by`, ae2.`edited_by`, ae3.`edited_by`, 
               ae4.`edited_by`, ae5.`edited_by`, ae6.`edited_by`)
IS NULL;

创建者和编辑器应该始终具有相同的
id
?只要您看到名为某物\u 1、某物\u 2等的表。。。警钟应该开始响了。您可能需要修改您的方案设计。短期内,您应该使用UNION将这些表“合并”(其中的相关列)到一个表中。
created_by
edited_by
可能会有所不同,这会让事情变得更困难。数据库设计真的很糟糕,但我无法进行更改:(创建者和编辑器应该始终具有相同的
id
?每当您看到名为\u 1、\u 2等的表时,就会响起警钟。您可能需要修改架构设计。短期内,您应该使用UNION来“合并”(中的相关列)将这些表合并为一个。
创建的和由编辑的可能不同,这使得事情变得更难。数据库设计非常糟糕,但我无法进行更改:(