数据库 - 比较2个无密钥表的方法

时间:2011-10-06 11:19:03

标签: sql database oracle comparison

我正在尝试研究如何比较两个无密钥(即没有列是主键或唯一的)表,这些表应该具有完全相同的数据。即将tablea从my_schema1直接迁移到my_schema2。

我在考虑一种可能的方法:

IF 
    count from 
    ((select * from my_schema1.tablea
    union
    select * from my_schema2.tablea))
    =
    count from
    ((select * from my_schema1.tablea
    union all
    select * from my_schema2.tablea) / 2)
 THEN
     --both tables would be identical (in record counts and all column values the same)
 ELSE
     --this means that the 2 tables are different in some way
 END IF

很高兴有功能:我宁愿通过消除指定列的需要使解决方案尽可能通用。

3 个答案:

答案 0 :(得分:0)

select count(*) 
from 
(
 ( select * from my_schema1.tablea 
   minus 
   select * from my_schema2.tablea
 )
 union 
 ( select * from my_schema2.tablea 
   minus 
   select * from my_schema1.tablea
 )
)

if count(*) = 0 then 
 THEN
     --both tables are identical 
 ELSE
     -- the 2 tables are different in some way
 end if;

答案 1 :(得分:0)

如果你没有重复项,你可以这样做......

SELECT
  (SELECT COUNT(*) FROM (SELECT * FROM table1 UNION SELECT * FROM table2)) AS unioned,
  (SELECT COUNT(*) FROM table1)                                            AS table1,
  (SELECT COUNT(*) FROM table2)                                            AS table2

如果两个表匹配,则所有三个数字应该相同。


如果存在重复项,可以使用相同的方法,方法是添加计数字段...

WITH
  table1 AS (SELECT a, b, c, d, COUNT(*) AS duplicates FROM table1 GROUP BY a, b, c, d),
  table2 AS (SELECT a, b, c, d, COUNT(*) AS duplicates FROM table2 GROUP BY a, b, c, d)
SELECT
  (SELECT COUNT(*) FROM (SELECT * FROM table1 UNION SELECT * FROM table2)) AS unioned,
  (SELECT COUNT(*) FROM table1)                                            AS table1,
  (SELECT COUNT(*) FROM table2)                                            AS table2

答案 2 :(得分:0)

假设下面有一列C。您需要将其扩展到完整的列列表(未在Oracle上进行测试,因此可能会出现一些小的语法问题,但一般方法应该有效)

WITH T1 AS
(
SELECT *,
       ROW_NUMBER() OVER (PARTITION BY C ORDER BY C) AS RN
FROM T              
), T2 AS
(
SELECT *,
       ROW_NUMBER() OVER (PARTITION BY C ORDER BY C) AS RN
FROM T       
), T3 AS
(
SELECT * FROM T1 
MINUS
SELECT * FROM T2
), T4 AS
(
SELECT * FROM T2 
MINUS
SELECT * FROM T1
)
SELECT * FROM T3
UNION ALL 
SELECT * FROM T4