在SQLite中,是否有一种方法可以测试两个表是否相同?
假设这两个表位于同一个文件中。因此,问题是,除了名称之外,表是否相同,即相同的模式、相同的内容。要比较表模式,请查看以下列表中的语句: 在比较中必须忽略表名本身;如果您有任何包含表名的列名或注释,则自动替换会更加困难 要比较内容,只需使用检查是否有其他表中没有的行:在SQLite中,是否有一种方法可以测试两个表是否相同?,sqlite,Sqlite,假设这两个表位于同一个文件中。因此,问题是,除了名称之外,表是否相同,即相同的模式、相同的内容。要比较表模式,请查看以下列表中的语句: 在比较中必须忽略表名本身;如果您有任何包含表名的列名或注释,则自动替换会更加困难 要比较内容,只需使用检查是否有其他表中没有的行: SELECT NOT EXISTS (SELECT * FROM This EXCEPT SELECT * FROM That) AND NOT EX
SELECT NOT EXISTS (SELECT * FROM This
EXCEPT
SELECT * FROM That)
AND NOT EXISTS (SELECT * FROM That
EXCEPT
SELECT * FROM This);
我相信以下几点就足够了:-
/*
Compare Schema and data in tables.
t1 is the SQL for the first table (mytable) with the table name changed to a common name (table)
t2 is the SQL for the second table (mytable_copy1) with the table changed to a common name (table)
(so if t1 and t2 are equal then the schema is the same)
tablecompare is the logical result of comparing the data of each table with the other table
except matching rows so if no rows exists then NOT EXISTS will be true (1) AND the two
and the result will be 1 if both tables exactly match each other.
*/
SELECT
(t1 = t1) AND tablecompare AS test FROM
(SELECT
replace(sql,'mytable','table') AS t1, -- change the table name to a common name
replace(sql,'mytable_copy1','table') AS t2, -- change the table name to a common name
(
SELECT NOT EXISTS (SELECT * FROM mytable EXCEPT SELECT * FROM mytable_copy1)
AND NOT EXISTS (SELECT * FROM mytable_copy1 EXCEPT SELECT * FROM mytable)
) AS tablecompare
FROM sqlite_master WHERE name = 'mytable'
)
- 请注意,这些表是mytable和mytable_copy1,因此将对它们进行更改以反映这两个表
/*
Table Compare
t1 is the SQL for the first table (mytable) with the table name replace by table
t2 is the SQL for the second table (mytable_copy1) again table name change to table
So if t1 = t2 then the schema is identical
t1count is the number of rows in the first table
t2count is the number of rows in the second table
So if the counts are the same then the tables may be identical
unioncount is the count of the union of the two tables (not union all) so duiplicates are dropped
therefore if unioncount is the same as either of the table counts then tables are identical
NOTE!!! this assumes tables are not WITHOUT ROWID tables (would have to omit the inclusion of rowid NOT TESTED)
the inclusion of rowid could be dropped (NOT TESTED) if there is an alias of rowid.
*/
SELECT
t1 = t1 AND t1count = t2count AND t1count = unioncount AS test FROM
(SELECT
replace(sql,'mytable','table') AS t1, -- change the table name to a common name
replace(sql,'mytable_copy1','table') AS t2, -- change the table name to a common name
(SELECT count() FROM mytable) AS t1count, -- get the number of rows
(SELECT count() FROM mytable_copy1) AS t2count, -- get the number of rows
(SELECT count() AS unioncount FROM
(SELECT rowid,* FROM mytable UNION SELECT rowid,* FROM mytable_copy1)) AS unioncount
FROM sqlite_master WHERE name = 'mytable'
) ;
如果表与0匹配,则两个解决方案都返回一个单行/列结果1。如果表不匹配,则返回0。
然而,它可以,但做单独的测试需要更少的时间/资源。e、 g.如果模式不匹配,则不执行任何操作,否则检查行计数,如果不匹配,则不执行实际检查数据的最终检查
测试使用以下表格进行测试:-
对于mytable和mytable_copy1:-
上述两种产品均按照以下标准生产了1台:-
以及:-
当下表(突出显示更改数据的mytable_copy2)时:-
结果是:-
以及:-
我在两个我知道相等的表上测试了您的解决方案,结果返回1。我同意,为了提高效率,最好先比较模式和行数。我的表大约有150万行和205列,上面显示的select语句需要几分钟的时间来执行。我不确定如何比较SQL中的模式,因为它们必须包含不同的表名。也许您的意思是将结果导入到编程环境中并在那里进行比较?这将是本网站通常的含义。;-)无论如何,您可以对
sql
值执行replace()
,然后比较它们(例如,分组方式)。
/*
Table Compare
t1 is the SQL for the first table (mytable) with the table name replace by table
t2 is the SQL for the second table (mytable_copy1) again table name change to table
So if t1 = t2 then the schema is identical
t1count is the number of rows in the first table
t2count is the number of rows in the second table
So if the counts are the same then the tables may be identical
unioncount is the count of the union of the two tables (not union all) so duiplicates are dropped
therefore if unioncount is the same as either of the table counts then tables are identical
NOTE!!! this assumes tables are not WITHOUT ROWID tables (would have to omit the inclusion of rowid NOT TESTED)
the inclusion of rowid could be dropped (NOT TESTED) if there is an alias of rowid.
*/
SELECT
t1 = t1 AND t1count = t2count AND t1count = unioncount AS test FROM
(SELECT
replace(sql,'mytable','table') AS t1, -- change the table name to a common name
replace(sql,'mytable_copy1','table') AS t2, -- change the table name to a common name
(SELECT count() FROM mytable) AS t1count, -- get the number of rows
(SELECT count() FROM mytable_copy1) AS t2count, -- get the number of rows
(SELECT count() AS unioncount FROM
(SELECT rowid,* FROM mytable UNION SELECT rowid,* FROM mytable_copy1)) AS unioncount
FROM sqlite_master WHERE name = 'mytable'
) ;