我正在将旧数据库合并到新数据库中。在新数据库中,我有四个数据库表:'task_clone', 'potential_task', 'task'
和'task_archive'
。
'task_clone'
包含从旧数据库中导入的task类型的所有数据库条目,我正在尝试将这些条目分布在新数据库的其他三个表中。 'task_clone'
因此是一个临时表。
'task_clone'
包含649个条目。数据的结构很难映射到新数据库,并且从'task_clone'
复制行之后,其他三个表条目的总和为566,这意味着'task_clone'
中有83个条目尚未映射到新结构中。
我正在尝试查询'task_clone'
来找出其他三个表中哪些条目不在'task_clone'
中。
所有三个表都包含列'task_id'
,该列对于每个任务条目都是唯一的ID。因此,我应该能够查询数据库并获得'task_id'
中的所有'task_clone'
列,以返回与其他三个表中的那些不匹配的整体。
我知道这在单个查询中应该可以实现,但是我似乎不太了解语法的正确性。我要去哪里错了,应该怎么写?我最初尝试过:
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个表的问题提供解决方案。此外,在我的问题中,我清楚地指出,我已经看过以前处理两个表的堆栈答案,并且在没有收到错误消息的情况下无法将它们转换为四个。
答案 0 :(得分:2)
鉴于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
答案 1 :(得分:1)
您可以使用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)
答案 2 :(得分:1)
我会使用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
的子查询,因为后者不能以直观的方式处理NULL
。如果任何表中的 any task_id
为NULL
,则外部查询将完全不返回任何行。这与NULL
在SQL中的含义一致,但这是违反直觉的。
NOT EXISTS
像您期望的那样对待NULL
-它们在给定的行上不匹配,但不会影响其他行的结果。