Mysql 如果两个表具有相同的数据,如何进行比较?

Mysql 如果两个表具有相同的数据,如何进行比较?,mysql,sql,linux,subquery,Mysql,Sql,Linux,Subquery,如果我有两个表,想知道它们是否有相同的数据,那么在MySQL中最简单的方法是什么? 我读过关于做相关子查询和联合的文章,但是这个查询大约有2页!不能真正理解它在做什么。一定有更简单的办法。 即使是,例如,让MySQL将表数据复制到文件并执行vimdiff,我也不确定这是否可行-是吗?-只是大声思考 更新 我只对表格数据感兴趣,对结构不感兴趣。这是为了澄清由于我的一个模棱两可的评论,你可以模拟一个完整的外部连接,然后返回右边或左边为空的行 select t1.* from table1 t1 L

如果我有两个表,想知道它们是否有相同的数据,那么在MySQL中最简单的方法是什么? 我读过关于做相关子查询和联合的文章,但是这个查询大约有2页!不能真正理解它在做什么。一定有更简单的办法。 即使是,例如,让MySQL将表数据复制到文件并执行vimdiff,我也不确定这是否可行-是吗?-只是大声思考

更新
我只对表格数据感兴趣,对结构不感兴趣。这是为了澄清由于我的一个模棱两可的评论,你可以模拟一个完整的外部连接,然后返回右边或左边为空的行

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

使用完全外部联接,您可以在其他表中显示其他行不可用的所有行。

使用以下查询:

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。它没有显示差异,只是一个二进制测试。

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

SELECT 1 FROM (
   SELECT * FROM table1
   UNION ALL
   SELECT * FROM table2
) t
GROUP BY col1, col2, col3
HAVING count(*) = 1
LIMIT 1
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
列出GROUP BY中的所有列以比较整个表

如果结果为空集,则两个表是相同的

如果要查看差异,请使用以下查询:

SELECT 1 FROM (
   SELECT * FROM table1
   UNION ALL
   SELECT * FROM table2
) t
GROUP BY col1, col2, col3
HAVING count(*) = 1
LIMIT 1
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
在“内部选择”中列出与“分组依据”中相同的列,再加上一列以区分这两个表。
我正在读A.Molinaro的SQL食谱,突然发现了一个解决方案。 它是基于表的 empempno、ename、job、经理、雇佣员工、sal、通信、部门 还有一个观点 v 具有相同的列但不同的行。mgr列和comm列可能为空,其他列可能不为空。 书中的解决方案很长,并没有显示所有的差异,尽管这是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
);
基本上,计算两个表中不同的行,并执行union而不是union all,以获得tmp.table UNIONALE。然后删除这两个表共有的行。 此处,表t1中的两行r1和表t2中的两行r2视为相同,如果
r1,t1中r1的计数=r2,t2中r2的计数,这相当于所有列上r1=r2,t1中r1的计数=t2中r2的计数。

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

表的大小是否可能重复?如果它们足够小,您可能会转储它们并将转储文件与diff进行比较-假设某个键正在对它们进行适当的索引和排序。。。否则,显示数据库的架构,或者至少有几张桌子…@BasileStarynkevitch:它们很大。但即使它们很小,我也不知道怎么做你的建议。如果你把它作为答案的一部分贴出来,我会很感兴趣的。我会的upvote@BasileStarynkevitch:为什么架构对这个问题很重要?我的问题没有一个特定的MySQL解决方案吗?@RobW:我对这个问题不感兴趣查找具有不同值的行。我想知道表A和表B是否完全相同。我不理解这一点。为什么选择计数?第三个子查询查找两个表中相同的行。但如果两个表中都有额外的行,它们就不会被注意到。所以我计算每个表中的行数,如果这等于相等的行数,就意味着没有多余的行。+1。但是如果它们不相同,我就看不出有什么不同。@Cratylus我更新了我的答案,我添加了一个查询变体来查看差异。+1.为什么不在查询的第二部分进行右连接并恢复顺序?没有原因,我只是倾向于左连接。我认为OP希望通过编程实现这一点。