【问题标题】:MYSQL return list of row IDs which are not present in other database tablesMYSQL 返回其他数据库表中不存在的行 ID 列表
【发布时间】: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 个表格的问题提供解决方案。此外,在我的问题中,我明确指出我已经查看了以前处理两个表的堆栈答案,我无法在没有收到错误消息的情况下将它们转换为四个。

【问题讨论】:

标签: mysql sql join


【解决方案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 就像您所期望的那样 - 它们在给定行上不匹配,但不会影响其他行中的结果。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-11-29
      • 1970-01-01
      • 2019-04-03
      • 2018-06-24
      • 2011-03-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多