我有两个表items
和items_archive
都由于存储过程错误而丢失了信息。
我有一个表items_restored
,我从文本备份中恢复了该表,其中包含许多不在items
或items_archive
中的项目,我需要最终插入items_restored
已进入items_archive
。
我能够很容易地找到一个比较结果,
SELECT ir.id, i_a.id
FROM items_restord as ir
LEFT JOIN items_archive as i_a ON ir.id = i_a.id
WHERE i_a.id IS NULL;
这给了我items_restored
中没有items_archive
中的id的列表,但是问题是其中某些ID可能出现在items
中。如果我在items
而不是items_archive
上运行上述查询,则会发生相同的问题,我看到丢失的内容,但很有可能丢失的ID在items_archive
中。
我最终需要运行INSERT
,我认为如果我根据这些查询来做一顿饭,那么很有可能最终要插入重复的记录,而这是我想要避免的。
我如何制作查询以同时检查items
和items_archive
ID并与我的items_restored
ID进行比较,以便避免重复?
编辑:我最终选择了全部合并,这是我在LEFT JOIN
之后做的。谢谢大家。
答案 0 :(得分:0)
您可以重复LEFT JOIN
:
SELECT ir.id --, i_a.id -- this is always NULL so why select it?
FROM items_restord ir LEFT JOIN
items_archive i_a
ON ir.id = i_a.id LEFT JOIN
items i
ON ir.id = i.id
WHERE i_a.id IS NULL AND i.id IS NULL;
我认为NOT EXISTS
是表达逻辑的一种更简洁的方法:
select ir.*
from items_restord ir
where not exists (select 1 from items_archive i_a where ir.id = i_a.id) and
not exists (select 1 from items i where ir.id = i.id);
答案 1 :(得分:0)
我建议合并语句。您将能够比较这些数据之间的所有数据,但是可以根据匹配,不匹配等条件设置条件,这可以减轻您指出的某些问题。但是,如果我记得的话,合并仅在SQL Server 2008+中可用,因此语法可能不可用,因为您仅标记了SQL。
MERGE INTO items_archive AS Target
USING (
SELECT ...
FROM items_restore AS Source (
...
)
)
ON (target.Id = source.Id)
WHEN MATCHED THEN UPDATE SET
...
WHEN NOT MATCHED BY TARGET THEN INSERT (
...
) VALUES (
...
)
WHEN NOT MATCHED BY SOURCE THEN DELETE
OUTPUT $action, Inserted.*, Deleted.*;
为简洁起见,我确实精简了代码,因为我不确定特定的列名,但是您也可以结合输出操作来指示查询容易完成的工作。但是,在同类表之间合并数据的好方法。
您提到找到丢失的数据,我的想法是,如果不存在匹配项,则会创建该匹配项并将其扔到输出日志中。