MYSQL 返回其他数据库表中不存在的行 ID 列表

Posted

技术标签:

【中文标题】MYSQL 返回其他数据库表中不存在的行 ID 列表【英文标题】:MYSQL return list of row IDs which are not present in other database tables 【发布时间】:2019-02-03 23:50:03 【问题描述】:

我正在将一个旧数据库合并到一个新数据库中。在新数据库中,我有四个数据库表:'task_clone', 'potential_task', 'task''task_archive'

'task_clone' 包含从旧数据库导入的任务类型的所有数据库条目,我正在尝试将这些条目分布在新数据库中的其他三个表中。 'task_clone' 因此是一个临时表。

'task_clone' 包含 649 个条目。数据结构不是很容易映射到新数据库,从'task_clone'复制行后,其他三个表条目的总和为566,这意味着'task_clone'中有83个条目尚未完成映射到新结构中。

我正在尝试查询'task_clone' 以找出其他三个表中的哪些条目不在'task_clone' 中。

所有三个表都包含列'task_id',它是每个任务条目的唯一ID。因此,我应该能够查询数据库并获取'task_clone' 中的所有'task_id' 列,返回与其他三个表中的不匹配的整体。

我知道这在单个查询中应该是可能的,但我似乎无法正确获取语法。我哪里错了,应该怎么写?我最初尝试过:

SELECT task_clone.task_id 
FROM task_clone 
WHERE 
    task_clone.task_id != potential_task.task_id 
    AND task_clone.task_id != task.task_id 
    AND task_clone.task_id != task_archive.task_id;

我还研究了使用两个表执行此操作的其他方法(即从一个表中返回不在另一个表中的值),但我找不到一个可以干净地转换为适用于更多解决方案的示例比两个表没有收到错误消息。感谢阅读。

注意这个被标记为重复的问题:这个问题与之前专门询问两个表的问题不是重复的,因为我的问题特别询问如何使用四个表。在引用的问题上提供的解决方案虽然使用大致相同的语法,但没有为 4 个表格的问题提供解决方案。此外,在我的问题中,我明确指出我已经查看了以前处理两个表的堆栈答案,我无法在没有收到错误消息的情况下将它们转换为四个。

【问题讨论】:

提示:... table1 LEFT JOIN table2 WHERE table1.column IS NULL 或简单的... table 1 WHERE id NOT IN(SELECT id FROM table2) 是的,但那是两张桌子,不是四张。 如果不能解决问题,我建议您提供示例数据和预期结果.. 我建议您阅读此Why should I provide an MCVE for what seems to me to be a very simple SQL query? 以提供它 感谢雷蒙德。我不知道关于元的建议。我认为问题不在于数据库的结构,而在于查询的结构,因此只发布代码。 Select from one table where not in another的可能重复 【参考方案1】:

鉴于task_id 是所有表中的主键,LEFT JOIN 方法似乎更加高效和简洁:

SELECT tc.*
FROM 
    task_clone tc
    LEFT JOIN potential_task pt ON pt.task_id = tc.task_id
    LEFT JOIN task t ON t.task_id = tc.task_id
    LEFT JOIN task_archive ta ON ta.task_id = tc.task_id
WHERE
    pt.task_id     IS NULL 
    AND t.task_id  IS NULL 
    AND ta.task_id IS NULL 

【讨论】:

【参考方案2】:

你能用 NOT IN 吗?

 SELECT task_clone.task_id FROM task_clone 
 WHERE task_clone.task_id NOT IN  (SELECT task_id from potential_task)
 AND task_clone.task_id NOT IN  (SELECT task_id from task)
 AND task_clone.task_id NOT IN  (SELECT task_id from task_archive)

【讨论】:

谢谢!这解决了我的问题。我不知道 NOT IN 子句。谢谢。它不会让我现在点击接受。我不断收到一条消息,说您可以在 5 分钟内接受。【参考方案3】:

我会使用NOT EXISTS:

SELECT tc.task_id
FROM task_clone tc
WHERE NOT EXiSTS (SELECT 1 FROM potential_task pt WHERE pt.task_id = tc.task_id) AND
      NOT EXiSTS (SELECT 1 FROM task t WHERE t.task_id = tc.task_id) AND
      NOT EXiSTS (SELECT 1 FROM task_archive ta WHERE ta.task_id = tc.task_id) ;

我更喜欢 NOT EXISTS 而不是带有子查询的 NOT IN,因为后者不能以直观的方式处理 NULLs。如果任何表中的 any task_idNULL,则外部查询将根本不返回任何行。这与NULL 在 SQL 中的含义是一致的,但它是违反直觉的。

NOT EXISTS 处理 NULLs 就像您所期望的那样 - 它们在给定行上不匹配,但不会影响其他行中的结果。

【讨论】:

以上是关于MYSQL 返回其他数据库表中不存在的行 ID 列表的主要内容,如果未能解决你的问题,请参考以下文章

MySQL删除具有引用不存在ID的参数的行

MySQL选择其他表中没有匹配列的行

获取表中不存在的 ID 列表

如何不选择其他表中不存在的行

MySQL内部连接查询以获取其他表中不存在的记录

在同一列中不存在某些 ID 的大表中选择数据。加快查询