MySQL中对比两张表行数据,找出temp_announcement的新增行
MySQL表行差异对比方案
为啥EXCEPT会报错?
MySQL 8.0.3版本之后才支持EXCEPT运算符,要是你用的是更早的版本,直接写肯定报错。就算版本够,EXCEPT默认会去重,如果你要保留重复的差异行,这个逻辑也不符合需求。
提取temp_announcement多出的行的具体方法
方法1:LEFT JOIN + IS NULL(通用所有版本)
这是MySQL里最稳妥的写法,不管版本新旧都能用,效率也高,前提是你有主键或者唯一标识列(比如id)。
假设两张表结构一致,用id作为唯一标识:
SELECT ta.* FROM temp_announcement ta LEFT JOIN announcement a ON ta.id = a.id WHERE a.id IS NULL;
如果没有单一主键,就得拿所有列来匹配(确保整行数据完全一致):
SELECT ta.* FROM temp_announcement ta LEFT JOIN announcement a ON ta.title = a.title AND ta.content = a.content AND ta.create_time = a.create_time -- 把所有需要对比的列都写上 WHERE a.title IS NULL;
方法2:NOT IN(注意NULL坑)
用这个方法的前提是,你用来匹配的列(比如id)没有NULL值,不然结果会是空的:
SELECT * FROM temp_announcement WHERE id NOT IN (SELECT id FROM announcement);
方法3:MySQL 8.0.3+ 正确用EXCEPT
如果你的MySQL版本在8.0.3及以上,直接这么写就行:
SELECT * FROM temp_announcement EXCEPT SELECT * FROM announcement;
要是需要保留重复的差异行,用EXCEPT ALL:
SELECT * FROM temp_announcement EXCEPT ALL SELECT * FROM announcement;
高效对比的技巧
- 用主键/唯一索引关联:靠主键或者唯一键匹配,MySQL能利用索引快速查找,比全表对比所有列快太多。
- 给关联列加索引:大数据量下,索引能避免全表扫描,大幅提升效率。
- 哈希值对比(适合多列大表):如果表的列特别多,可以计算每行的哈希值(比如MD5),再对比哈希值,减少列的对比量:
SELECT ta.* FROM temp_announcement ta LEFT JOIN announcement a ON MD5(CONCAT(COALESCE(ta.col1, ''), COALESCE(ta.col2, ''), COALESCE(ta.col3, ''))) = MD5(CONCAT(COALESCE(a.col1, ''), COALESCE(a.col2, ''), COALESCE(a.col3, ''))) WHERE a.col1 IS NULL;
这里用COALESCE是为了处理列中的NULL值,避免CONCAT直接返回NULL导致哈希对比失效。
内容的提问来源于stack exchange,提问作者Soumya Mannava
相关产品推荐
相关产品推荐

