基本上,我们有一个表(original table
),它被备份到另一个表(backup table
);因此这两个表具有完全相同的模式。
在开始时,两个表(original table
和backup table
)包含完全相同的数据集。由于某种原因,经过一段时间后,我需要验证original table
中的数据集是否已更改。
为了做到这一点,我必须将original table
中的数据集与backup table
进行比较。
假设original table
具有以下架构:
create table LemmasMapping (
lemma1 int,
lemma2 int,
index ix_lemma1 using btree (lemma1),
index ix_lemma2 using btree (lemma2)
)
我如何实现数据集比较?
更新:该表没有主键。它只是存储两个ID之间的映射。
答案 0 :(得分:32)
您可以使用CHECKSUM TABLE并比较结果。您甚至可以alter the table启用实时校验和,以便它们可以持续可用。
CHECKSUM TABLE original_table, backup_table;
它不要求表具有主键。
答案 1 :(得分:19)
SELECT * FROM Table1
UNION
SELECT * FROM Table2
如果您获得的记录大于两个表中的任何一个,则它们没有相同的数据。
答案 2 :(得分:16)
我会写三个查询。
内部联接以获取两个表中存在主键的行,但其中一个或多个列的值存在差异。这将获取原始的更改行。
左外连接用于获取原始表中的行,但不包括备份表中的行(即原始行中的行具有备份中不存在的主键)。这将返回插入原始行的行。
右外连接,用于拾取原始中不再存在的备份行。这将返回已从原始文件中删除的行。
您可以将三个查询合并在一起以返回单个结果集。如果你这样做,你需要添加一个列来指示它是什么类型的行(更新,插入或删除)。
通过一些努力,您可以使用完全外部联接在一个查询中执行此操作。注意外连接,因为它们在不同的SQL引擎中表现不同。放在where子句中的谓词,而不是join子句有时可以将外连接转换为内连接。
答案 3 :(得分:1)
select count(*)
from lemmas as original_table
full join backup_table using (lemma_id)
where backup_table.lemma_id is null
or original_table.lemma_id is null
or original_table.lemma != backup_table.lemma
null的完整联接/检查应该包括添加或删除以及更改。
答案 4 :(得分:1)
尝试以下方法比较两个表:
SELECT 'different' FROM DUAL WHERE EXISTS(
SELECT * FROM (
SELECT /*DISTINCT*/ +1 AS chk,a.c1,a.c2,a.c3 FROM a
UNION ALL
SELECT /*DISTINCT*/ +1 AS chk,b.c1,b.c2,b.c3 FROM b
) c
GROUP BY c1,c2,c3
HAVING SUM(chk)<>2
)
UNION SELECT 'equal' FROM DUAL
LIMIT 1;
答案 5 :(得分:0)
对于使用MS SQL Server的懒惰或更厌恶SQL的开发人员,我建议使用SQL Delta(www.sqldelta.com)进行此操作以及任何其他数据库差异类型的工作。它具有出色的GUI,快速准确,可以区分所有数据库对象,生成并运行必要的更改脚本,同步整个数据库。这是DBA的下一个最好的事情; - )
我认为RedGate提供了一个名为SQL Compare的类似工具。我相信最新版Visual Studio(2010)的一些版本也包含了一个非常相似的工具。
答案 6 :(得分:0)
请尝试使用以下方法确定两个表是否完全相同,当没有任何类型的主键且表中没有重复的行时,使用以下逻辑:
第1步 - 测试TABLEA上的重复行
如果SELECT DISTINCT * FROM TABLEA
与
具有相同的行数SELECT * FROM TABLEA
然后转到下一步,否则您无法使用此方法...
第2步 - 测试TABLEB上的重复行
如果SELECT DISTINCT * FROM TABLEB
与
具有相同的行数SELECT * FROM TABLEB
然后转到下一步,否则您无法使用此方法...
第3步 - 在每列上INNER JOIN TABLEA到TABLEB
如果以下查询的行数与步骤1和2中的行数相同,则表格相同:
SELECT
*
FROM
TABLEA
INNER JOIN TABLEA ON
TABLEA.column1 = TABLEB.column1
AND TABLEA.column2 = TABLEB.column2
AND TABLEA.column3 = TABLEB.column3
--etc...for every column
请注意,此方法不一定会测试不同的数据类型,并且可能无法处理不可连接的数据类型(如VARBINARY)
欢迎反馈!
答案 7 :(得分:0)
1:表C1和C2的首次获取计数。 C1和C2应该相等。 C1和C2可以从以下查询中获取
select count(*) from table1
如果C1和C2不相等,则表不相同。
2:查找表DC1和DC2的不同计数。 DC1和DC2应该相等。可以使用以下查询找到不同记录的数量:
select count(*) from (select distinct * from table1)
如果DC1和DC2不相等,则表不相同。
3:现在获得通过对2个表执行联合获得的记录数。使其成为U。使用以下查询获取2个表的并集中的记录数:
SELECT count (*)
FROM
(SELECT *
FROM table1
UNION
SELECT *
FROM table2)
如果两个表的不同计数等于通过执行两个表的并集获得的记录数,则可以说两个表中的数据相同。即 DC1 = U,DC2 = U
答案 8 :(得分:0)
但是,您也可以在 SQL Server 中使用“Except”关键字。
SELECT Col1, Col2, Col3, Col4, Col5 FROM Table_1
EXCEPT
SELECT Col1, Col2, Col3, Col4, Col5 FROM Table_2
如果查询返回任何行:它们不相同。
如果查询没有返回任何行:它们是相同的。