如果我有 2 个表并想查找它们是否具有相同的数据,那么最直接的方法是什么MySQL
?
我已经阅读了有关执行相关子查询的信息,UNION ALL
但是该查询大约有 2 页(!)并且不能真正遵循它在做什么。必须有更简单的方法。
即使它是例如MySQL
将表数据复制到文件并执行vimdiff
(我不确定这是否可能-是吗?-只是大声思考)。
更新
我只对表数据感兴趣,而不对结构感兴趣。这是为了澄清,因为我做了一个模棱两可的评论
如果您只想尽可能高效地判断表是否相同,请使用以下查询:
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
加上一列以区分两个表。只要把它扔在那里,你就可以模拟一个完整的外连接,然后返回右侧或左侧为空的行。
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,您可以显示其他表中另一行不可用的所有行。
使用以下查询:
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
如果表相等,这将返回。它没有显示差异,它只是一个二进制测试。
当我遇到一个解决方案时,我正在阅读 A.Molinaro 的 SQL Cookbook。它基于表 emp(empno,ename,job,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,count of r1 in t1) = (r2, count of r2 in t2),相当于r1=r2(在所有列上)和 (t1 中 r1 的计数) = (t2 中 r2 的计数)。
如果表足够小,您可以将两个表导出为 csv 文件,然后复制其中一个表并将它们与另一个表并排粘贴。您可以逐行查看输出是否相同。