如何比较2个表是否具有相同的数据?

时间:2013-07-01 19:07:08

标签: mysql sql linux subquery

如果我有2个表并且想要查找它们是否具有相同的数据,那么在MySQL中最简单的方法是什么? 我已经阅读了关于执行相关子查询和UNION ALL但是这个查询大约是2页(!)并且不能真正遵循它正在做的事情。必须有一个更简单的方法 即使是例如make MySQL将表数据复制到文件并执行vimdiff(我不确定这是否可能 - 是吗? - 只是大声思考)。

更新
我只对表数据感兴趣,而不是结构。这是为了澄清由于我做出的含糊不清的评论

5 个答案:

答案 0 :(得分:4)

如果您只是想尽可能高效地判断表格是否相同,请使用以下查询:

SELECT 1 FROM (
   SELECT * FROM table1
   UNION ALL
   SELECT * FROM table2
) t
GROUP BY col1, col2, col3
HAVING count(*) = 1
LIMIT 1
  • 列出GROUP BY中的所有列以比较整个表格。

  • 如果结果为空集,则两个表相同。

如果您想查看差异,请使用此查询:

SELECT * FROM (
   SELECT 'table1' tname, col1, col2, col3 FROM table1
   UNION ALL
   SELECT 'table2' tname, col1, col2, col3 FROM table2
) t
GROUP BY col1, col2, col3
HAVING count(*) = 1
  • 列出内部SELECT中与GROUP BY中相同的列,以及用于区分这两个表的列。

答案 1 :(得分:1)

只要把它扔出去,就可以模拟一个完整的外连接,然后返回右边或左边为空的行。

select t1.* 
from table1 t1
LEFT OUTER JOIN table2 t2
ON t1.col1 = t2.col1
AND t1.col2 = t2.col2
AND ...
WHERE t2.id is null
UNION
select t2.* 
from table2 t2
LEFT OUTER JOIN table1 t1
ON t2.col1 = t1.col1
AND t2.col2 = t1.col2
AND ...
WHERE t1.id is null

使用FULL OUTER JOIN,您可以显示另一行中另一行不可用的所有行。

答案 2 :(得分:0)

使用以下查询:

SELECT c1 = cjoin AND c2 = cjoin equiv
FROM (SELECT COUNT(*) c1 FROM Table1) t1,
     (SELECT COUNT(*) c2 FROM Table2) t2,
     (SELECT COUNT(*) cjoin
      FROM Table1 t1
      JOIN Table2 t2
      ON t1.col1 = t2.col1 AND t1.col2 = t2.col2 AND t1.col3 = t2.col3 ...) tjoin

假设表具有唯一键,如果表相等,则返回equiv = 1。它没有显示差异,它只是一个二元测试。

答案 3 :(得分:0)

当我遇到一个解决方案时,我正在阅读A.Molinaro的SQL Cookbook。 它基于表格     的 EMP(EMPNO,ENAME,工作,MGR,HIREDATE,SAL,COMM,DEPTNO) 和一个观点     的 V 它具有相同的列但行不同。 mgr comm 列可能 NULL ,其他列则不是。 书中的解决方案很长,并没有显示出所有的差异,尽管这是3.7中陈述的问题。 我编写了我的解决方案,它更短并显示所有差异(表示两个表中具有不同计数的所有行)。

select * from
# those which are contained in the (distinct) union of (col1,col2,...,coln, count) of both tables:
( select empno,ename,job,mgr,hiredate,comm,deptno, count(*) cnt from emp group by empno,ename,job,mgr,hiredate,comm,deptno
   union
  select empno,ename,job,mgr,hiredate,comm,deptno, count(*) cnt from V group by empno,ename,job,mgr,hiredate,comm,deptno
) as unionOfBoth
where (empno,ename,job,mgr,hiredate,comm,deptno,cnt)
not in
# those which are contained in the intersection of both tables with the equal number of counts:
( select e.empno,e.ename,e.job,e.mgr,e.hiredate,e.comm,e.deptno,e.cnt
  from
  (select empno, ename,job,mgr,hiredate,comm,deptno, count(*) cnt from emp group by empno,ename,job,mgr,hiredate,comm,deptno) e,
  (select empno, ename,job,mgr,hiredate,comm,deptno, count(*) cnt from V group by empno,ename,job,mgr,hiredate,comm,deptno) v
  where 
   e.empno = v.empno 
   and e.ename = v.ename
   and e.job = v.job
   and ifnull(e.mgr,0) = ifnull(v.mgr,0)
   and e.hiredate = v.mgr
   and e.deptno = v.deptno
   and ifnull(e.comm,0) = ifnull(v.comm,0)
   and e.cnt = v.cnt
);

基本上,你计算两个表中的不同行并进行联合(而不是全部联合)以获取tmp.table unionBoth 。然后删除这两个表共有的行。 这里,来自表t1的两行r1和来自表t2的r2被认为是相同的,如果     (r1,t1中r1的计数)=(r2,t2中r2的计数),相当于 r1 = r2 (在所有列上) (t1中r1的计数)=(t2中的r2计数)

答案 4 :(得分:0)

如果表足够小,则可以将两个表都导出为csv文件,然后复制其中一个表并与另一个表并排粘贴。您可以逐行查看输出是否相同。